diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 6d2e9dae1..18556b71b 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -755,6 +755,13 @@ br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & resul return BR_DONE; } + if (arg1 == arg2 && !m_util.is_numeral(arg2)) { + expr_ref zero(m_util.mk_int(0), m()), abs(m()); + mk_abs_core(arg2, abs); + result = m().mk_ite(m().mk_eq(arg2, zero), m_util.mk_mod(zero, zero), abs); + return BR_DONE; + } + // mod is idempotent on non-zero modulus. expr* t1, *t2; if (m_util.is_mod(arg1, t1, t2) && t2 == arg2 && m_util.is_numeral(arg2, v2, is_int) && is_int && !v2.is_zero()) { diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 4f041cc41..0f2437982 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -18,22 +18,22 @@ Revision History: --*/ -#include "qe/nlqsat.h" -#include "nlsat/nlsat_solver.h" -#include "nlsat/nlsat_explain.h" -#include "nlsat/nlsat_assignment.h" -#include "qe/qsat.h" -#include "ast/rewriter/quant_hoist.h" -#include "nlsat/tactic/goal2nlsat.h" -#include "ast/expr2var.h" #include "util/uint_set.h" +#include "ast/expr2var.h" #include "ast/ast_util.h" -#include "tactic/core/tseitin_cnf_tactic.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/ast_pp.h" #include "ast/for_each_expr.h" #include "ast/rewriter/rewriter.h" #include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/quant_hoist.h" +#include "qe/nlqsat.h" +#include "qe/qsat.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_explain.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/tactic/goal2nlsat.h" +#include "tactic/core/tseitin_cnf_tactic.h" namespace qe { @@ -292,8 +292,8 @@ namespace qe { nlsat::var_vector vs; m_solver.vars(l, vs); TRACE("qe", m_solver.display(tout, l); tout << "\n";); - for (unsigned i = 0; i < vs.size(); ++i) { - level.merge(m_rvar2level[vs[i]]); + for (unsigned v : vs) { + level.merge(m_rvar2level[v]); } set_level(l.var(), level); return level; @@ -438,9 +438,10 @@ namespace qe { class div_rewriter_cfg : public default_rewriter_cfg { ast_manager& m; arith_util a; + expr_ref m_zero; vector
m_divs; public: - div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m) {} + div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m), m_zero(a.mk_real(0), m) {} ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1])) { @@ -448,6 +449,11 @@ namespace qe { m_divs.push_back(div(m, args[0], args[1], to_app(result))); return BR_DONE; } + if (is_decl_of(f, a.get_family_id(), OP_DIV_0) && sz == 1 && !a.is_numeral(args[0])) { + result = m.mk_fresh_const("div", a.mk_real()); + m_divs.push_back(div(m, args[0], m_zero, to_app(result))); + return BR_DONE; + } return BR_FAILED; } vector
const& divs() const { return m_divs; } @@ -497,7 +503,11 @@ namespace qe { if (a.is_power(n, n1, n2) && a.is_numeral(n2, r) && r.is_unsigned()) { return; } - if (a.is_div(n, n1, n2) && s.m_mode == qsat_t) { + if (a.is_div(n) && s.m_mode == qsat_t) { + m_has_divs = true; + return; + } + if (a.is_div0(n) && s.m_mode == qsat_t) { m_has_divs = true; return; } @@ -539,7 +549,7 @@ namespace qe { app_ref_vector pvars(m); expr_ref_vector paxioms(m); purify(fml, pvars, paxioms); - if (pvars.empty()) { + if (paxioms.empty()) { return; } expr_ref ante = mk_and(paxioms); @@ -552,6 +562,7 @@ namespace qe { } } + void reset() { //m_solver.reset(); m_asms.reset(); @@ -618,10 +629,12 @@ namespace qe { app_ref_vector vars(m); bool is_forall = false; pred_abs abs(m); + abs.get_free_vars(fml, vars); insert_set(m_free_vars, vars); qvars.push_back(vars); vars.reset(); + if (m_mode == elim_t) { is_forall = true; hoist.pull_quantifier(is_forall, fml, vars); @@ -638,6 +651,7 @@ namespace qe { qvars.push_back(vars); } while (!vars.empty()); + SASSERT(qvars.size() >= 2); SASSERT(qvars.back().empty()); ackermanize_div(is_forall, qvars, fml); diff --git a/src/qe/qsat.cpp b/src/qe/qsat.cpp index abd396818..713ecfe77 100644 --- a/src/qe/qsat.cpp +++ b/src/qe/qsat.cpp @@ -20,23 +20,23 @@ Notes: --*/ -#include "smt/smt_kernel.h" -#include "qe/qe_mbp.h" -#include "smt/params/smt_params.h" +#include "ast/expr_abstract.h" #include "ast/ast_util.h" #include "ast/rewriter/quant_hoist.h" #include "ast/ast_pp.h" -#include "model/model_v2_pp.h" -#include "qe/qsat.h" -#include "ast/expr_abstract.h" -#include "qe/qe.h" -#include "ast/rewriter/label_rewriter.h" -#include "ast/rewriter/expr_replacer.h" #include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_v2_pp.h" #include "model/model_evaluator.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" #include "smt/smt_solver.h" #include "solver/solver.h" #include "solver/mus.h" +#include "qe/qsat.h" +#include "qe/qe_mbp.h" +#include "qe/qe.h" +#include "ast/rewriter/label_rewriter.h" namespace qe { diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index fe1cf5260..bde9e0e98 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -31,14 +31,15 @@ Notes: #include "tactic/smtlogics/qfaufbv_tactic.h" #include "tactic/smtlogics/qfufbv_tactic.h" #include "tactic/smtlogics/qfidl_tactic.h" +#include "tactic/smtlogics/nra_tactic.h" #include "tactic/portfolio/default_tactic.h" +#include "tactic/portfolio/fd_solver.h" #include "tactic/ufbv/ufbv_tactic.h" #include "tactic/fpa/qffp_tactic.h" #include "tactic/smtlogics/qfufnra_tactic.h" #include "muz/fp/horn_tactic.h" #include "smt/smt_solver.h" #include "sat/sat_solver/inc_sat_solver.h" -#include "tactic/portfolio/fd_solver.h" #include "ast/rewriter/bv_rewriter.h" #include "solver/solver2tactic.h" @@ -78,6 +79,8 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_uflra_tactic(m, p); else if (logic=="LRA") return mk_lra_tactic(m, p); + else if (logic=="NRA") + return mk_nra_tactic(m, p); else if (logic=="LIA") return mk_lia_tactic(m, p); else if (logic=="UFBV")