/*++ Copyright (c) 2014 Microsoft Corporation Module Name: card2bv_tactic.cpp Abstract: Tactic for converting Pseudo-Boolean constraints to BV Author: Nikolaj Bjorner (nbjorner) 2014-03-20 Notes: --*/ #pragma once #include "util/params.h" #include "ast/pb_decl_plugin.h" #include "ast/rewriter/th_rewriter.h" #include "ast/rewriter/rewriter.h" #include #include "util/sorting_network.h" class ast_manager; class tactic; namespace pb { class card2bv_rewriter { public: typedef expr* pliteral; typedef ptr_vector pliteral_vector; private: ast_manager& m; arith_util au; pb_util pb; bv_util bv; psort_nw m_sort; expr_ref_vector m_lemmas; expr_ref_vector m_trail; unsigned get_num_bits(func_decl* f); void mk_bv(func_decl * f, unsigned sz, expr * const* args, expr_ref & result); br_status mk_shannon(func_decl * f, unsigned sz, expr * const* args, expr_ref & result); expr* negate(expr* e); expr* mk_ite(expr* c, expr* hi, expr* lo); bool is_or(func_decl* f); bool is_and(func_decl* f); bool is_atmost1(func_decl* f, unsigned sz, expr * const* args, expr_ref& result); expr_ref mk_atmost1(unsigned sz, expr * const* args); void mk_at_most_1_small(bool last, unsigned n, pliteral const* xs, expr_ref_vector& result, expr_ref_vector& ors); public: card2bv_rewriter(ast_manager& m); br_status mk_app_core(func_decl * f, unsigned sz, expr * const* args, expr_ref & result); void mk_assert(func_decl * f, unsigned sz, expr * const* args, expr_ref & result, expr_ref_vector& lemmas); // definitions used for sorting network pliteral mk_false() { return m.mk_false(); } pliteral mk_true() { return m.mk_true(); } pliteral mk_max(pliteral a, pliteral b) { return trail(m.mk_or(a, b)); } pliteral mk_min(pliteral a, pliteral b) { return trail(m.mk_and(a, b)); } pliteral mk_not(pliteral a) { if (m.is_not(a,a)) return a; return trail(m.mk_not(a)); } std::ostream& pp(std::ostream& out, pliteral lit); pliteral fresh(); pliteral trail(pliteral l); void mk_clause(unsigned n, pliteral const* lits); }; struct card2bv_rewriter_cfg : public default_rewriter_cfg { card2bv_rewriter m_r; bool rewrite_patterns() const { return false; } bool flat_assoc(func_decl * f) const { return false; } br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { result_pr = nullptr; return m_r.mk_app_core(f, num, args, result); } card2bv_rewriter_cfg(ast_manager & m):m_r(m) {} }; class card_pb_rewriter : public rewriter_tpl { card2bv_rewriter_cfg m_cfg; pb_util pb; expr_ref_vector m_lemmas; public: card_pb_rewriter(ast_manager & m): rewriter_tpl(m, false, m_cfg), m_cfg(m), pb(m), m_lemmas(m) {} void rewrite(expr* e, expr_ref& result); expr_ref_vector& lemmas() { return m_lemmas; } }; }; tactic * mk_card2bv_tactic(ast_manager & m, params_ref const & p = params_ref()); /* ADD_TACTIC("card2bv", "convert pseudo-boolean constraints to bit-vectors.", "mk_card2bv_tactic(m, p)") */