3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

enable cardinality constraints in nla2bv

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-02-19 18:17:07 +01:00
parent 509f80b1db
commit caa15ea04d
4 changed files with 60 additions and 43 deletions

View file

@ -1779,41 +1779,30 @@ namespace sat {
} }
#endif #endif
IF_VERBOSE(10, verbose_stream() << "\"checking model\"\n";); if (m_clone) {
if (!check_clauses(m_model)) { IF_VERBOSE(10, verbose_stream() << "\"checking model\"\n";);
throw solver_exception("check model failed"); if (!check_clauses(m_model)) {
throw solver_exception("check model failed");
}
} }
if (m_config.m_drat) m_drat.check_model(m_model); if (m_config.m_drat) {
m_drat.check_model(m_model);
}
// m_mc.set_solver(nullptr);
m_mc(m_model); m_mc(m_model);
if (!gparams::get_ref().get_bool("model_validate", false)) { if (m_clone && !check_clauses(m_model)) {
return;
}
if (!check_clauses(m_model)) {
IF_VERBOSE(1, verbose_stream() << "failure checking clauses on transformed model\n";); IF_VERBOSE(1, verbose_stream() << "failure checking clauses on transformed model\n";);
IF_VERBOSE(10, m_mc.display(verbose_stream())); IF_VERBOSE(10, m_mc.display(verbose_stream()));
//IF_VERBOSE(0, display_units(verbose_stream())); IF_VERBOSE(10, display_model(verbose_stream()));
//IF_VERBOSE(0, display(verbose_stream()));
IF_VERBOSE(1, for (bool_var v = 0; v < num; v++) verbose_stream() << v << ": " << m_model[v] << "\n";);
throw solver_exception("check model failed"); throw solver_exception("check model failed");
} }
TRACE("sat", for (bool_var v = 0; v < num; v++) tout << v << ": " << m_model[v] << "\n";); if (m_clone && !m_clone->check_model(m_model)) {
IF_VERBOSE(1, m_mc.display(verbose_stream()));
if (m_clone) { IF_VERBOSE(1, display_units(verbose_stream()));
IF_VERBOSE(1, verbose_stream() << "\"checking model (on original set of clauses)\"\n";); throw solver_exception("check model failed (for cloned solver)");
if (!m_clone->check_model(m_model)) {
//IF_VERBOSE(0, display(verbose_stream()));
//IF_VERBOSE(0, display_watches(verbose_stream()));
IF_VERBOSE(1, m_mc.display(verbose_stream()));
IF_VERBOSE(1, display_units(verbose_stream()));
//IF_VERBOSE(0, m_clone->display(verbose_stream() << "clone\n"));
throw solver_exception("check model failed (for cloned solver)");
}
} }
} }
@ -3546,6 +3535,14 @@ namespace sat {
return true; return true;
} }
std::ostream& solver::display_model(std::ostream& out) const {
unsigned num = num_vars();
for (bool_var v = 0; v < num; v++) {
out << v << ": " << m_model[v] << "\n";
}
return out;
}
void solver::display_binary(std::ostream & out) const { void solver::display_binary(std::ostream & out) const {
unsigned sz = m_watches.size(); unsigned sz = m_watches.size();
for (unsigned l_idx = 0; l_idx < sz; l_idx++) { for (unsigned l_idx = 0; l_idx < sz; l_idx++) {

View file

@ -668,6 +668,7 @@ namespace sat {
void display_watches(std::ostream & out) const; void display_watches(std::ostream & out) const;
void display_watches(std::ostream & out, literal lit) const; void display_watches(std::ostream & out, literal lit) const;
void display_dimacs(std::ostream & out) const override; void display_dimacs(std::ostream & out) const override;
std::ostream& display_model(std::ostream& out) const;
void display_wcnf(std::ostream & out, unsigned sz, literal const* lits, unsigned const* weights) const; void display_wcnf(std::ostream & out, unsigned sz, literal const* lits, unsigned const* weights) const;
void display_assignment(std::ostream & out) const; void display_assignment(std::ostream & out) const;
std::ostream& display_justification(std::ostream & out, justification const& j) const; std::ostream& display_justification(std::ostream & out, justification const& j) const;

View file

@ -21,6 +21,7 @@ Notes:
#include "tactic/tactical.h" #include "tactic/tactical.h"
#include "ast/arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include "ast/bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
#include "ast/pb_decl_plugin.h"
#include "ast/for_each_expr.h" #include "ast/for_each_expr.h"
#include "ast/rewriter/expr_replacer.h" #include "ast/rewriter/expr_replacer.h"
#include "util/optional.h" #include "util/optional.h"
@ -85,13 +86,18 @@ class nla2bv_tactic : public tactic {
TRACE("nla2bv", g.display(tout); TRACE("nla2bv", g.display(tout);
tout << "Muls: " << count_mul(g) << "\n"; tout << "Muls: " << count_mul(g) << "\n";
); );
tactic_report report("nla->bv", g);
m_fmc = alloc(generic_model_converter, m_manager, "nla2bv"); m_fmc = alloc(generic_model_converter, m_manager, "nla2bv");
m_bounds(g); m_bounds(g);
collect_power2(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"); 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); substitute_vars(g);
TRACE("nla2bv", g.display(tout << "substitute vars\n");); TRACE("nla2bv", g.display(tout << "substitute vars\n"););
reduce_bv2int(g); reduce_bv2int(g);
@ -308,27 +314,30 @@ class nla2bv_tactic : public tactic {
class get_uninterp_proc { class get_uninterp_proc {
imp& m_imp; imp& m_imp;
arith_util& a;
ast_manager& m;
pb_util pb;
ptr_vector<app> m_vars; ptr_vector<app> m_vars;
bool m_in_supported_fragment; bool m_in_supported_fragment;
public: 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; } ptr_vector<app> const& vars() { return m_vars; }
void operator()(var * n) { void operator()(var * n) {
m_in_supported_fragment = false; m_in_supported_fragment = false;
} }
void operator()(app* n) { void operator()(app* n) {
arith_util& a = m_imp.m_arith; if (a.is_int(n) && is_uninterp_const(n)) {
ast_manager& m = a.get_manager(); TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, m) << "\n";);
if (a.is_int(n) &&
is_uninterp_const(n)) {
m_vars.push_back(n); m_vars.push_back(n);
} }
else if (a.is_real(n) && else if (a.is_real(n) && is_uninterp_const(n)) {
is_uninterp_const(n)) {
m_vars.push_back(n); m_vars.push_back(n);
} }
else if (m.is_bool(n) && is_uninterp_const(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) || else if (!(a.is_mul(n) ||
a.is_add(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_le(n) ||
m_imp.m_bv2real.is_pos_lt(n) || m_imp.m_bv2real.is_pos_lt(n) ||
n->get_family_id() == a.get_manager().get_basic_family_id())) { 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_in_supported_fragment = false;
} }
m_imp.update_num_bits(n); 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 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); get_uninterp_proc fe_var(*this);
for_each_expr_at(fe_var, g); for_each_expr_at(fe_var, g);
for (unsigned i = 0; i < fe_var.vars().size(); ++i) { for (unsigned i = 0; i < fe_var.vars().size(); ++i) {
add_var(fe_var.vars()[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 { class count_mul_proc {

View file

@ -27,6 +27,7 @@ Notes:
#include "sat/tactic/sat_tactic.h" #include "sat/tactic/sat_tactic.h"
#include "tactic/arith/nla2bv_tactic.h" #include "tactic/arith/nla2bv_tactic.h"
#include "tactic/arith/lia2card_tactic.h" #include "tactic/arith/lia2card_tactic.h"
#include "tactic/arith/card2bv_tactic.h"
#include "tactic/core/ctx_simplify_tactic.h" #include "tactic/core/ctx_simplify_tactic.h"
#include "tactic/core/cofactor_term_ite_tactic.h" #include "tactic/core/cofactor_term_ite_tactic.h"
#include "nlsat/tactic/qfnra_nlsat_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_ctx_simplify_tactic(m), ctx_simp_p),
using_params(mk_simplify_tactic(m), pull_ite_p), using_params(mk_simplify_tactic(m), pull_ite_p),
mk_elim_uncnstr_tactic(m), 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))); 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) { static tactic * mk_qfnia_smt_solver(ast_manager& m, params_ref const& p) {
params_ref simp_p = p; params_ref simp_p = p;
simp_p.set_bool("som", true); // expand into sums of monomials 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) { 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( return and_then(
mk_report_verbose_tactic("(qfnia-tactic)", 10), mk_report_verbose_tactic("(qfnia-tactic)", 10),
mk_qfnia_premable(m, p), mk_qfnia_premable(m, p),
or_else(mk_qfnia_sat_solver(m, p), mk_qfnia_sat_solver(m, p)
try_for(mk_qfnia_smt_solver(m, p), 2000),
mk_qfnia_nlsat_solver(m, p), // or_else(mk_qfnia_sat_solver(m, p),
mk_qfnia_smt_solver(m, p)) // try_for(mk_qfnia_smt_solver(m, p), 2000),
// mk_qfnia_nlsat_solver(m, p),
// mk_qfnia_smt_solver(m, p))
); );
} }