3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

streamline pb solver interface and naming after removal of xor

This commit is contained in:
Nikolaj Bjorner 2021-02-28 12:32:04 -08:00
parent 13f05ae9dc
commit 026065ff71
73 changed files with 1131 additions and 1201 deletions

View file

@ -23,6 +23,10 @@ Notes:
#include "util/small_object_allocator.h"
#include "sat/sat_elim_eqs.h"
namespace pb {
class solver;
};
namespace sat {
struct pp_prefix {
@ -66,7 +70,7 @@ namespace sat {
reslimit m_rlimit;
friend class ccc;
friend class ba_solver;
friend class pb::solver;
struct config {
double m_dl_success;

View file

@ -31,6 +31,10 @@ Revision History:
#include "util/statistics.h"
#include "util/params.h"
namespace pb {
class solver;
}
namespace sat {
class solver;
@ -50,7 +54,7 @@ namespace sat {
};
class simplifier {
friend class ba_solver;
friend class pb::solver;
friend class elim_vars;
solver & s;
unsigned m_num_calls;

View file

@ -47,6 +47,10 @@ Revision History:
#include "util/scoped_ptr_vector.h"
#include "util/scoped_limit_trail.h"
namespace pb {
class solver;
};
namespace sat {
/**
@ -210,7 +214,7 @@ namespace sat {
friend class probing;
friend class simplifier;
friend class scc;
friend class ba_solver;
friend class pb::solver;
friend class anf_simplifier;
friend class cut_simplifier;
friend class parallel;

View file

@ -9,11 +9,6 @@ z3_add_component(sat_smt
array_model.cpp
array_solver.cpp
atom2bool_var.cpp
ba_card.cpp
ba_constraint.cpp
ba_internalize.cpp
ba_pb.cpp
ba_solver.cpp
bv_ackerman.cpp
bv_delay_internalize.cpp
bv_internalize.cpp
@ -28,6 +23,11 @@ z3_add_component(sat_smt
euf_relevancy.cpp
euf_solver.cpp
fpa_solver.cpp
pb_card.cpp
pb_constraint.cpp
pb_internalize.cpp
pb_pb.cpp
pb_solver.cpp
q_clause.cpp
q_ematch.cpp
q_eval.cpp

View file

@ -19,7 +19,7 @@ Author:
#include "ast/ast_ll_pp.h"
#include "sat/sat_solver.h"
#include "sat/smt/sat_smt.h"
#include "sat/smt/ba_solver.h"
#include "sat/smt/pb_solver.h"
#include "sat/smt/bv_solver.h"
#include "sat/smt/euf_solver.h"
#include "sat/smt/array_solver.h"
@ -112,7 +112,7 @@ namespace euf {
datatype_util dt(m);
recfun::util rf(m);
if (pb.get_family_id() == fid)
ext = alloc(sat::ba_solver, *this, fid);
ext = alloc(pb::solver, *this, fid);
else if (bvu.get_family_id() == fid)
ext = alloc(bv::solver, *this, fid);
else if (au.get_family_id() == fid)

View file

@ -15,33 +15,14 @@ Author:
--*/
#include "sat/smt/ba_card.h"
#include "sat/smt/ba_solver.h"
#include "sat/smt/pb_card.h"
#include "sat/smt/pb_solver.h"
#include "sat/sat_simplifier.h"
namespace ba {
// -----------------------
// pb_base
bool pb_base::well_formed() const {
uint_set vars;
if (lit() != sat::null_literal) vars.insert(lit().var());
for (unsigned i = 0; i < size(); ++i) {
bool_var v = get_lit(i).var();
if (vars.contains(v)) return false;
if (get_coeff(i) > k()) return false;
vars.insert(v);
}
return true;
}
// ----------------------
// card
namespace pb {
card::card(unsigned id, literal lit, literal_vector const& lits, unsigned k) :
pb_base(tag_t::card_t, id, lit, lits.size(), get_obj_size(lits.size()), k) {
constraint(tag_t::card_t, id, lit, lits.size(), get_obj_size(lits.size()), k) {
for (unsigned i = 0; i < size(); ++i) {
m_lits[i] = lits[i];
}
@ -64,7 +45,7 @@ namespace ba {
return false;
}
double card::get_reward(ba::solver_interface const& s, sat::literal_occs_fun& literal_occs) const {
double card::get_reward(solver_interface const& s, sat::literal_occs_fun& literal_occs) const {
unsigned k = this->k(), slack = 0;
bool do_add = s.get_config().m_lookahead_reward == sat::heule_schur_reward;
double to_add = do_add ? 0 : 1;
@ -262,7 +243,7 @@ namespace ba {
lbool card::eval(sat::model const& m) const {
unsigned trues = 0, undefs = 0;
for (literal l : *this) {
switch (ba::value(m, l)) {
switch (pb::value(m, l)) {
case l_true: trues++; break;
case l_undef: undefs++; break;
default: break;

View file

@ -18,27 +18,12 @@ Author:
#pragma once
#include "sat/sat_types.h"
#include "sat/smt/ba_constraint.h"
#include "sat/smt/pb_constraint.h"
namespace ba {
namespace pb {
// base class for pb and cardinality constraints
class pb_base : public constraint {
protected:
unsigned m_k;
public:
pb_base(ba::tag_t t, unsigned id, literal l, unsigned sz, size_t osz, unsigned k) :
constraint(t, id, l, sz, osz), m_k(k) {
VERIFY(k < 4000000000);
}
virtual void set_k(unsigned k) { VERIFY(k < 4000000000); m_k = k; }
virtual unsigned get_coeff(unsigned i) const { UNREACHABLE(); return 0; }
unsigned k() const { return m_k; }
bool well_formed() const override;
};
class card : public pb_base {
class card : public constraint {
literal m_lits[0];
public:
static size_t get_obj_size(unsigned num_lits) { return sat::constraint_base::obj_size(sizeof(card) + num_lits * sizeof(literal)); }
@ -54,7 +39,7 @@ namespace ba {
literal get_lit(unsigned i) const override { return m_lits[i]; }
void set_lit(unsigned i, literal l) override { m_lits[i] = l; }
unsigned get_coeff(unsigned i) const override { return 1; }
double get_reward(ba::solver_interface const& s, sat::literal_occs_fun& occs) const override;
double get_reward(solver_interface const& s, sat::literal_occs_fun& occs) const override;
std::ostream& display(std::ostream& out) const override;
std::ostream& display(std::ostream& out, solver_interface const& s, bool values) const override;
void clear_watch(solver_interface& s) override;

View file

@ -15,9 +15,9 @@ Author:
--*/
#include "sat/smt/ba_constraint.h"
#include "sat/smt/pb_constraint.h"
namespace ba {
namespace pb {
unsigned constraint::fold_max_var(unsigned w) const {
if (lit() != sat::null_literal) w = std::max(w, lit().var());
@ -55,4 +55,17 @@ namespace ba {
}
}
bool constraint::well_formed() const {
uint_set vars;
if (lit() != sat::null_literal) vars.insert(lit().var());
for (unsigned i = 0; i < size(); ++i) {
bool_var v = get_lit(i).var();
if (vars.contains(v)) return false;
if (get_coeff(i) > k()) return false;
vars.insert(v);
}
return true;
}
}

View file

@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
ba_constraint.h
pb_constraint.h
Abstract:
@ -18,9 +18,9 @@ Revision History:
--*/
#pragma once
#include "sat/smt/ba_solver_interface.h"
#include "sat/smt/pb_solver_interface.h"
namespace ba {
namespace pb {
enum class tag_t {
card_t,
@ -28,29 +28,30 @@ namespace ba {
};
class card;
class pb;
class pb_base;
class pbc;
inline lbool value(sat::model const& m, literal l) { return l.sign() ? ~m[l.var()] : m[l.var()]; }
class constraint {
protected:
tag_t m_tag;
bool m_removed;
bool m_removed { false };
literal m_lit;
literal m_watch;
unsigned m_glue;
unsigned m_psm;
literal m_watch { sat::null_literal };
unsigned m_glue { 0 };
unsigned m_psm { 0 };
unsigned m_size;
size_t m_obj_size;
bool m_learned;
bool m_learned { false };
unsigned m_id;
bool m_pure; // is the constraint pure (only positive occurrences)
bool m_pure { false }; // is the constraint pure (only positive occurrences)
unsigned m_k;
void display_lit(std::ostream& out, solver_interface const& s, literal lit, unsigned sz, bool values) const;
public:
constraint(tag_t t, unsigned id, literal l, unsigned sz, size_t osz):
m_tag(t), m_removed(false), m_lit(l), m_watch(sat::null_literal), m_glue(0), m_psm(0), m_size(sz), m_obj_size(osz), m_learned(false), m_id(id), m_pure(false) {
constraint(tag_t t, unsigned id, literal l, unsigned sz, size_t osz, unsigned k):
m_tag(t), m_lit(l), m_size(sz), m_obj_size(osz), m_id(id), m_k(k) {
VERIFY(k < 400000000);
}
sat::ext_constraint_idx cindex() const { return sat::constraint_base::mem2base(this); }
void deallocate(small_object_allocator& a) { a.deallocate(obj_size(), sat::constraint_base::mem2base_ptr(this)); }
@ -79,10 +80,9 @@ namespace ba {
size_t obj_size() const { return m_obj_size; }
card& to_card();
pb& to_pb();
pbc& to_pb();
card const& to_card() const;
pb const& to_pb() const;
pb_base const& to_pb_base() const;
pbc const& to_pb() const;
bool is_card() const { return m_tag == tag_t::card_t; }
bool is_pb() const { return m_tag == tag_t::pb_t; }
@ -103,7 +103,6 @@ namespace ba {
virtual void swap(unsigned i, unsigned j) { UNREACHABLE(); }
virtual literal get_lit(unsigned i) const { UNREACHABLE(); return sat::null_literal; }
virtual void set_lit(unsigned i, literal l) { UNREACHABLE(); }
virtual bool well_formed() const { return true; }
virtual void negate() { UNREACHABLE(); }
virtual bool is_extended_binary(literal_vector& r) const { return false; }
@ -111,7 +110,12 @@ namespace ba {
virtual std::ostream& display(std::ostream& out) const = 0;
virtual std::ostream& display(std::ostream& out, solver_interface const& s, bool values) const = 0;
virtual void init_use_list(sat::ext_use_list& ul) const = 0;
virtual void set_k(unsigned k) { VERIFY(k < 4000000000); m_k = k; }
virtual unsigned get_coeff(unsigned i) const { UNREACHABLE(); return 0; }
unsigned k() const { return m_k; }
bool well_formed() const;
class iterator {
constraint const& c;
unsigned idx;

View file

@ -16,24 +16,24 @@ Author:
--*/
#include "sat/smt/ba_solver.h"
#include "sat/smt/pb_solver.h"
#include "ast/pb_decl_plugin.h"
namespace sat {
namespace pb {
void ba_solver::internalize(expr* e, bool redundant) {
void solver::internalize(expr* e, bool redundant) {
internalize(e, false, false, redundant);
}
literal ba_solver::internalize(expr* e, bool sign, bool root, bool redundant) {
literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
flet<bool> _redundant(m_is_redundant, redundant);
if (m_pb.is_pb(e))
return internalize_pb(e, sign, root);
UNREACHABLE();
return null_literal;
return sat::null_literal;
}
literal ba_solver::internalize_pb(expr* e, bool sign, bool root) {
literal solver::internalize_pb(expr* e, bool sign, bool root) {
SASSERT(m_pb.is_pb(e));
app* t = to_app(e);
rational k = m_pb.get_k(t);
@ -60,16 +60,16 @@ namespace sat {
default:
UNREACHABLE();
}
return null_literal;
return sat::null_literal;
}
void ba_solver::check_unsigned(rational const& c) {
void solver::check_unsigned(rational const& c) {
if (!c.is_unsigned()) {
throw default_exception("unsigned coefficient expected");
}
}
void ba_solver::convert_to_wlits(app* t, sat::literal_vector const& lits, svector<wliteral>& wlits) {
void solver::convert_to_wlits(app* t, sat::literal_vector const& lits, svector<wliteral>& wlits) {
for (unsigned i = 0; i < lits.size(); ++i) {
rational c = m_pb.get_coeff(t, i);
check_unsigned(c);
@ -77,20 +77,20 @@ namespace sat {
}
}
void ba_solver::convert_pb_args(app* t, literal_vector& lits) {
void solver::convert_pb_args(app* t, literal_vector& lits) {
for (expr* arg : *t) {
lits.push_back(si.internalize(arg, m_is_redundant));
s().set_external(lits.back().var());
}
}
void ba_solver::convert_pb_args(app* t, svector<wliteral>& wlits) {
void solver::convert_pb_args(app* t, svector<wliteral>& wlits) {
sat::literal_vector lits;
convert_pb_args(t, lits);
convert_to_wlits(t, lits, wlits);
}
literal ba_solver::convert_pb_le(app* t, bool root, bool sign) {
literal solver::convert_pb_le(app* t, bool root, bool sign) {
rational k = m_pb.get_k(t);
k.neg();
svector<wliteral> wlits;
@ -109,8 +109,8 @@ namespace sat {
k1 += wl.first;
}
}
add_pb_ge(null_bool_var, wlits, k1);
return null_literal;
add_pb_ge(sat::null_bool_var, wlits, k1);
return sat::null_literal;
}
else {
bool_var v = s().add_var(true);
@ -122,7 +122,7 @@ namespace sat {
}
literal ba_solver::convert_pb_ge(app* t, bool root, bool sign) {
literal solver::convert_pb_ge(app* t, bool root, bool sign) {
rational k = m_pb.get_k(t);
check_unsigned(k);
svector<wliteral> wlits;
@ -137,7 +137,7 @@ namespace sat {
}
}
add_pb_ge(sat::null_bool_var, wlits, k1);
return null_literal;
return sat::null_literal;
}
else {
sat::bool_var v = s().add_var(true);
@ -148,14 +148,14 @@ namespace sat {
}
}
literal ba_solver::convert_pb_eq(app* t, bool root, bool sign) {
literal solver::convert_pb_eq(app* t, bool root, bool sign) {
rational k = m_pb.get_k(t);
SASSERT(k.is_unsigned());
svector<wliteral> wlits;
convert_pb_args(t, wlits);
bool base_assert = (root && !sign && s().num_user_scopes() == 0);
bool_var v1 = base_assert ? null_bool_var : s().add_var(true);
bool_var v2 = base_assert ? null_bool_var : s().add_var(true);
bool_var v1 = base_assert ? sat::null_bool_var : s().add_var(true);
bool_var v2 = base_assert ? sat::null_bool_var : s().add_var(true);
add_pb_ge(v1, wlits, k.get_unsigned());
k.neg();
for (wliteral& wl : wlits) {
@ -165,7 +165,7 @@ namespace sat {
check_unsigned(k);
add_pb_ge(v2, wlits, k.get_unsigned());
if (base_assert) {
return null_literal;
return sat::null_literal;
}
else {
literal l1(v1, false), l2(v2, false);
@ -180,7 +180,7 @@ namespace sat {
}
}
literal ba_solver::convert_at_least_k(app* t, rational const& k, bool root, bool sign) {
literal solver::convert_at_least_k(app* t, rational const& k, bool root, bool sign) {
SASSERT(k.is_unsigned());
literal_vector lits;
convert_pb_args(t, lits);
@ -190,8 +190,8 @@ namespace sat {
for (literal& l : lits) l.neg();
k2 = lits.size() + 1 - k2;
}
add_at_least(null_bool_var, lits, k2);
return null_literal;
add_at_least(sat::null_bool_var, lits, k2);
return sat::null_literal;
}
else {
bool_var v = s().add_var(true);
@ -204,7 +204,7 @@ namespace sat {
}
}
literal ba_solver::convert_at_most_k(app* t, rational const& k, bool root, bool sign) {
literal solver::convert_at_most_k(app* t, rational const& k, bool root, bool sign) {
SASSERT(k.is_unsigned());
literal_vector lits;
convert_pb_args(t, lits);
@ -217,8 +217,8 @@ namespace sat {
for (literal& l : lits) l.neg();
k2 = lits.size() + 1 - k2;
}
add_at_least(null_bool_var, lits, k2);
return null_literal;
add_at_least(sat::null_bool_var, lits, k2);
return sat::null_literal;
}
else {
bool_var v = s().add_var(true);
@ -230,12 +230,12 @@ namespace sat {
}
}
literal ba_solver::convert_eq_k(app* t, rational const& k, bool root, bool sign) {
literal solver::convert_eq_k(app* t, rational const& k, bool root, bool sign) {
SASSERT(k.is_unsigned());
literal_vector lits;
convert_pb_args(t, lits);
bool_var v1 = (root && !sign) ? null_bool_var : s().add_var(true);
bool_var v2 = (root && !sign) ? null_bool_var : s().add_var(true);
bool_var v1 = (root && !sign) ? sat::null_bool_var : s().add_var(true);
bool_var v2 = (root && !sign) ? sat::null_bool_var : s().add_var(true);
add_at_least(v1, lits, k.get_unsigned());
for (literal& l : lits) {
l.neg();
@ -254,11 +254,11 @@ namespace sat {
return l;
}
else {
return null_literal;
return sat::null_literal;
}
}
expr_ref ba_solver::get_card(std::function<expr_ref(sat::literal)>& lit2expr, ba::card const& c) {
expr_ref solver::get_card(std::function<expr_ref(sat::literal)>& lit2expr, card const& c) {
ptr_buffer<expr> lits;
for (sat::literal l : c) {
lits.push_back(lit2expr(l));
@ -271,7 +271,7 @@ namespace sat {
return fml;
}
expr_ref ba_solver::get_pb(std::function<expr_ref(sat::literal)>& lit2expr, pb const& p) {
expr_ref solver::get_pb(std::function<expr_ref(sat::literal)>& lit2expr, pbc const& p) {
ptr_buffer<expr> lits;
vector<rational> coeffs;
for (auto const& wl : p) {
@ -287,13 +287,13 @@ namespace sat {
return fml;
}
bool ba_solver::to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) {
bool solver::to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) {
for (auto* c : constraints()) {
switch (c->tag()) {
case ba::tag_t::card_t:
case pb::tag_t::card_t:
fmls.push_back(get_card(l2e, c->to_card()));
break;
case ba::tag_t::pb_t:
case pb::tag_t::pb_t:
fmls.push_back(get_pb(l2e, c->to_pb()));
break;
}

View file

@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
ba_pb.cpp
pb_pb.cpp
Abstract:
@ -15,30 +15,25 @@ Author:
--*/
#include "sat/smt/ba_pb.h"
#include "sat/smt/pb_pb.h"
namespace ba {
namespace pb {
pb& constraint::to_pb() {
pbc& constraint::to_pb() {
SASSERT(is_pb());
return static_cast<pb&>(*this);
return static_cast<pbc&>(*this);
}
pb const& constraint::to_pb() const {
pbc const& constraint::to_pb() const {
SASSERT(is_pb());
return static_cast<pb const&>(*this);
}
pb_base const& constraint::to_pb_base() const {
SASSERT(is_pb() || is_card());
return static_cast<pb_base const&>(*this);
return static_cast<pbc const&>(*this);
}
// -----------------------------------
// pb
pb::pb(unsigned id, literal lit, svector<wliteral> const& wlits, unsigned k) :
pb_base(tag_t::pb_t, id, lit, wlits.size(), get_obj_size(wlits.size()), k),
pbc::pbc(unsigned id, literal lit, svector<wliteral> const& wlits, unsigned k) :
constraint(tag_t::pb_t, id, lit, wlits.size(), get_obj_size(wlits.size()), k),
m_slack(0),
m_num_watch(0),
m_max_sum(0) {
@ -48,7 +43,7 @@ namespace ba {
update_max_sum();
}
void pb::update_max_sum() {
void pbc::update_max_sum() {
m_max_sum = 0;
for (unsigned i = 0; i < size(); ++i) {
m_wlits[i].first = std::min(k(), m_wlits[i].first);
@ -59,7 +54,7 @@ namespace ba {
}
}
void pb::negate() {
void pbc::negate() {
m_lit.neg();
unsigned w = 0, m = 0;
for (unsigned i = 0; i < m_size; ++i) {
@ -76,21 +71,21 @@ namespace ba {
VERIFY(w >= m_k && m_k > 0);
}
bool pb::is_watching(literal l) const {
bool pbc::is_watching(literal l) const {
for (unsigned i = 0; i < m_num_watch; ++i) {
if ((*this)[i].second == l) return true;
}
return false;
}
bool pb::is_cardinality() const {
bool pbc::is_cardinality() const {
if (size() == 0) return false;
unsigned w = (*this)[0].first;
for (wliteral wl : *this) if (w != wl.first) return false;
return true;
}
double pb::get_reward(ba::solver_interface const& s, sat::literal_occs_fun& occs) const {
double pbc::get_reward(solver_interface const& s, sat::literal_occs_fun& occs) const {
unsigned k = this->k(), slack = 0;
bool do_add = s.get_config().m_lookahead_reward == sat::heule_schur_reward;
double to_add = do_add ? 0 : 1;
@ -114,7 +109,7 @@ namespace ba {
}
void pb::clear_watch(solver_interface& s) {
void pbc::clear_watch(solver_interface& s) {
reset_watch();
for (unsigned i = 0; i < num_watch(); ++i) {
unwatch_literal(s, (*this)[i].second);
@ -125,7 +120,7 @@ namespace ba {
// watch a prefix of literals, such that the slack of these is >= k
bool pb::init_watch(solver_interface& s) {
bool pbc::init_watch(solver_interface& s) {
SASSERT(well_formed());
auto& p = *this;
clear_watch(s);
@ -198,7 +193,7 @@ namespace ba {
}
std::ostream& pb::display(std::ostream& out) const {
std::ostream& pbc::display(std::ostream& out) const {
bool first = true;
for (wliteral wl : *this) {
if (!first) out << "+ ";
@ -209,7 +204,7 @@ namespace ba {
return out << " >= " << k();
}
std::ostream& pb::display(std::ostream& out, solver_interface const& s, bool values) const {
std::ostream& pbc::display(std::ostream& out, solver_interface const& s, bool values) const {
auto const& p = *this;
if (p.lit() != sat::null_literal) out << p.lit() << " == ";
if (values) {
@ -244,7 +239,7 @@ namespace ba {
return out << ">= " << p.k() << "\n";
}
bool pb::validate_unit_propagation(solver_interface const& s, literal alit) const {
bool pbc::validate_unit_propagation(solver_interface const& s, literal alit) const {
if (lit() != sat::null_literal && s.value(lit()) != l_true)
return false;
@ -260,11 +255,11 @@ namespace ba {
return sum < k();
}
lbool pb::eval(sat::model const& m) const {
lbool pbc::eval(sat::model const& m) const {
auto const& p = *this;
unsigned trues = 0, undefs = 0;
for (wliteral wl : p) {
switch (ba::value(m, wl.second)) {
switch (pb::value(m, wl.second)) {
case l_true: trues += wl.first; break;
case l_undef: undefs += wl.first; break;
default: break;
@ -275,7 +270,7 @@ namespace ba {
return l_undef;
}
lbool pb::eval(solver_interface const& s) const {
lbool pbc::eval(solver_interface const& s) const {
auto const& p = *this;
unsigned trues = 0, undefs = 0;
for (wliteral wl : p) {
@ -290,13 +285,13 @@ namespace ba {
return l_undef;
}
void pb::init_use_list(sat::ext_use_list& ul) const {
void pbc::init_use_list(sat::ext_use_list& ul) const {
auto idx = cindex();
for (auto l : *this)
ul.insert(l.second, idx);
}
bool pb::is_blocked(sat::simplifier& sim, literal lit) const {
bool pbc::is_blocked(sat::simplifier& sim, literal lit) const {
unsigned weight = 0, offset = 0;
for (wliteral l2 : *this) {
if (~l2.second == lit) {

View file

@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
ba_pb.h
pb_pb.h
Abstract:
@ -18,19 +18,19 @@ Author:
#pragma once
#include "sat/sat_types.h"
#include "sat/smt/ba_card.h"
#include "sat/smt/pb_card.h"
namespace ba {
namespace pb {
class pb : public pb_base {
class pbc : public constraint {
unsigned m_slack;
unsigned m_num_watch;
unsigned m_max_sum;
wliteral m_wlits[0];
public:
static size_t get_obj_size(unsigned num_lits) { return sat::constraint_base::obj_size(sizeof(pb) + num_lits * sizeof(wliteral)); }
pb(unsigned id, literal lit, svector<wliteral> const& wlits, unsigned k);
static size_t get_obj_size(unsigned num_lits) { return sat::constraint_base::obj_size(sizeof(pbc) + num_lits * sizeof(wliteral)); }
pbc(unsigned id, literal lit, svector<wliteral> const& wlits, unsigned k);
literal lit() const { return m_lit; }
wliteral operator[](unsigned i) const { return m_wlits[i]; }
wliteral& operator[](unsigned i) { return m_wlits[i]; }
@ -52,7 +52,7 @@ namespace ba {
literal get_lit(unsigned i) const override { return m_wlits[i].second; }
void set_lit(unsigned i, literal l) override { m_wlits[i].second = l; }
unsigned get_coeff(unsigned i) const override { return m_wlits[i].first; }
double get_reward(ba::solver_interface const& s, sat::literal_occs_fun& occs) const override;
double get_reward(solver_interface const& s, sat::literal_occs_fun& occs) const override;
void clear_watch(solver_interface& s) override;
std::ostream& display(std::ostream& out) const override;
std::ostream& display(std::ostream& out, solver_interface const& s, bool values) const override;

File diff suppressed because it is too large Load diff

View file

@ -25,23 +25,22 @@ Revision History:
#include "sat/sat_big.h"
#include "sat/smt/sat_smt.h"
#include "sat/smt/sat_th.h"
#include "sat/smt/ba_constraint.h"
#include "sat/smt/ba_card.h"
#include "sat/smt/ba_pb.h"
#include "sat/smt/pb_constraint.h"
#include "sat/smt/pb_card.h"
#include "sat/smt/pb_pb.h"
#include "util/small_object_allocator.h"
#include "util/scoped_ptr_vector.h"
#include "util/sorting_network.h"
#include "ast/pb_decl_plugin.h"
namespace sat {
namespace pb {
typedef ba::constraint constraint;
typedef ba::wliteral wliteral;
typedef ba::card card;
typedef ba::pb_base pb_base;
typedef ba::pb pb;
typedef pb::constraint constraint;
typedef pb::wliteral wliteral;
typedef pb::card card;
typedef pb::pbc pbc;
class ba_solver : public euf::th_solver, public ba::solver_interface {
class solver : public euf::th_solver, public pb::solver_interface {
friend class local_search;
@ -78,16 +77,16 @@ namespace sat {
bool contains(literal l) const { for (auto wl : m_wlits) if (wl.second == l) return true; return false; }
};
sat_internalizer& si;
sat::sat_internalizer& si;
pb_util m_pb;
lookahead* m_lookahead{ nullptr };
sat::lookahead* m_lookahead{ nullptr };
stats m_stats;
small_object_allocator m_allocator;
ptr_vector<ba::constraint> m_constraints;
ptr_vector<ba::constraint> m_learned;
ptr_vector<ba::constraint> m_constraint_to_reinit;
ptr_vector<constraint> m_constraints;
ptr_vector<constraint> m_learned;
ptr_vector<constraint> m_constraint_to_reinit;
unsigned_vector m_constraint_to_reinit_lim;
unsigned m_constraint_to_reinit_last_sz{ 0 };
unsigned m_constraint_id{ 0 };
@ -111,12 +110,12 @@ namespace sat {
typedef sat::literal pliteral;
typedef sat::literal_vector pliteral_vector;
ba_solver& s;
solver& s;
pliteral m_true;
pliteral_vector m_lits;
ba_sort(ba_solver& s): s(s), m_true(null_literal) {}
ba_sort(solver& s): s(s), m_true(sat::null_literal) {}
pliteral mk_false();
pliteral mk_true();
pliteral mk_not(pliteral l);
@ -137,7 +136,7 @@ namespace sat {
// simplification routines
vector<svector<constraint*>> m_cnstr_use_list;
use_list m_clause_use_list;
sat::use_list m_clause_use_list;
bool m_simplify_change{ false };
bool m_clause_removed{ false };
bool m_constraint_removed{ false };
@ -149,13 +148,13 @@ namespace sat {
euf::th_solver* clone_aux(ast_manager& m, sat::solver& s, sat::sat_internalizer& si, euf::theory_id id);
bool subsumes(card& c1, card& c2, literal_vector& comp);
bool subsumes(card& c1, clause& c2, bool& self);
bool subsumes(card& c1, sat::clause& c2, bool& self);
bool subsumed(card& c1, literal l1, literal l2);
bool subsumes(pb const& p1, pb_base const& p2);
void subsumes(pb& p1, literal lit);
void subsumption(pb& p1);
bool subsumes(pbc const& p1, constraint const& p2);
void subsumes(pbc& p1, literal lit);
void subsumption(pbc& p1);
void binary_subsumption(card& c1, literal lit);
void clause_subsumption(card& c1, literal lit, clause_vector& removed_clauses);
void clause_subsumption(card& c1, literal lit, sat::clause_vector& removed_clauses);
void card_subsumption(card& c1, literal lit);
unsigned get_num_unblocked_bin(literal l);
literal get_min_occurrence_literal(card const& c);
@ -165,9 +164,8 @@ namespace sat {
unsigned elim_pure();
bool elim_pure(literal lit);
void unit_strengthen();
void unit_strengthen(big& big, ba::constraint& cs);
void unit_strengthen(big& big, pb_base& p);
void subsumption(ba::constraint& c1);
void unit_strengthen(sat::big& big, constraint& cs);
void subsumption(pb::constraint& c1);
void subsumption(card& c1);
void gc_half(char const* _method);
void update_psm(constraint& c) const;
@ -178,23 +176,21 @@ namespace sat {
unsigned use_count(literal lit) const { return m_cnstr_use_list[lit.index()].size() + m_clause_use_list.get(lit).size(); }
void cleanup_clauses();
void cleanup_clauses(clause_vector& clauses);
void cleanup_clauses(sat::clause_vector& clauses);
void cleanup_constraints();
void cleanup_constraints(ptr_vector<constraint>& cs, bool learned);
void remove_constraint(constraint& c, char const* reason);
void gc_vars(unsigned num_vars, ptr_vector<constraint>& cs);
// constraints
constraint& index2constraint(size_t idx) const { return *reinterpret_cast<constraint*>(constraint_base::from_index(idx)->mem()); }
constraint& index2constraint(size_t idx) const { return *reinterpret_cast<constraint*>(sat::constraint_base::from_index(idx)->mem()); }
void pop_constraint();
// void watch_literal(wliteral w, pb& p);
void add_constraint(constraint* c);
bool init_watch(constraint& c);
void init_watch(bool_var v);
void clear_watch(constraint& c);
lbool add_assign(constraint& c, literal l);
bool incremental_mode() const;
void simplify(constraint& c);
void set_conflict(constraint& c, literal lit) override;
void assign(constraint& c, literal lit) override;
bool assigned_above(literal above, literal below);
@ -206,7 +202,7 @@ namespace sat {
void attach_constraint(constraint const& c);
void detach_constraint(constraint const& c);
lbool eval(constraint const& c) const;
lbool eval(model const& m, constraint const& c) const;
lbool eval(sat::model const& m, constraint const& c) const;
lbool eval(lbool a, lbool b) const;
void assert_unconstrained(literal lit, literal_vector const& lits);
void flush_roots(constraint& c);
@ -214,7 +210,7 @@ namespace sat {
void split_root(constraint& c);
unsigned next_id() { return m_constraint_id++; }
void set_non_learned(constraint& c);
double get_reward(literal l, ext_justification_idx idx, literal_occs_fun& occs) const override;
double get_reward(literal l, sat::ext_justification_idx idx, sat::literal_occs_fun& occs) const override;
// cardinality
lbool add_assign(card& c, literal lit);
@ -225,25 +221,24 @@ namespace sat {
void recompile(card& c);
bool clausify(card& c);
bool clausify(literal lit, unsigned n, literal const* lits, unsigned k);
lbool eval(card const& c) const;
lbool eval(model const& m, card const& c) const;
// pb functionality
unsigned m_a_max{ 0 };
lbool add_assign(pb& p, literal alit);
void add_index(pb& p, unsigned index, literal lit);
void get_antecedents(literal l, pb const& p, literal_vector & r);
void split_root(pb_base& p);
void simplify(pb_base& p);
void simplify2(pb& p);
bool is_cardinality(pb const& p);
void flush_roots(pb& p);
void recompile(pb& p);
bool clausify(pb& p);
bool is_cardinality(pb const& p, literal_vector& lits);
lbool eval(pb const& p) const;
lbool eval(model const& m, pb const& p) const;
lbool add_assign(pbc& p, literal alit);
void add_index(pbc& p, unsigned index, literal lit);
void get_antecedents(literal l, pbc const& p, literal_vector & r);
void simplify(constraint& p);
void simplify2(pbc& p);
bool is_cardinality(pbc const& p);
void flush_roots(pbc& p);
void recompile(pbc& p);
bool clausify(pbc& p);
bool is_cardinality(pbc const& p, literal_vector& lits);
lbool eval(pbc const& p) const;
lbool eval(model const& m, constraint const& p) const;
// RoundingPb conflict resolution
lbool resolve_conflict_rs();
@ -275,17 +270,17 @@ namespace sat {
if (m_lookahead) return m_lookahead->inconsistent();
return m_solver->inconsistent();
}
inline watch_list& get_wlist(literal l) override { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
inline watch_list const& get_wlist(literal l) const override { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
inline void assign(literal l, justification j) override {
inline sat::watch_list& get_wlist(literal l) override { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
inline sat:: watch_list const& get_wlist(literal l) const override { return m_lookahead ? m_lookahead->get_wlist(l) : m_solver->get_wlist(l); }
inline void assign(literal l, sat::justification j) override {
if (m_lookahead) m_lookahead->assign(l);
else m_solver->assign(l, j);
}
inline void set_conflict(justification j, literal l) override {
inline void set_conflict(sat::justification j, literal l) override {
if (m_lookahead) m_lookahead->set_conflict();
else m_solver->set_conflict(j, l);
}
inline config const& get_config() const override {
inline sat::config const& get_config() const override {
return m_lookahead ? m_lookahead->get_config() : m_solver->get_config();
}
@ -311,20 +306,20 @@ namespace sat {
// validation utilities
bool validate_conflict(card const& c) const;
bool validate_conflict(pb const& p) const;
bool validate_conflict(pbc const& p) const;
bool validate_assign(literal_vector const& lits, literal lit);
bool validate_lemma();
bool validate_ineq(ineq const& ineq) const;
bool validate_unit_propagation(pb const& p, literal_vector const& r, literal alit) const;
bool validate_unit_propagation(pbc const& p, literal_vector const& r, literal alit) const;
bool validate_conflict(literal_vector const& lits, ineq& p);
bool validate_watch_literals() const;
bool validate_watch_literal(literal lit) const;
bool validate_watched_constraint(constraint const& c) const;
bool validate_watch(pb const& p, literal alit) const;
bool validate_watch(pbc const& p, literal alit) const;
bool is_watching(literal lit, constraint const& c) const;
literal translate_to_sat(solver& s, u_map<bool_var>& translation, ineq const& pb);
literal translate_to_sat(solver& s, u_map<bool_var>& translation, ineq& a, ineq& b);
literal translate_to_sat(solver& s, u_map<bool_var>& translation, literal lit);
literal translate_to_sat(sat::solver& s, u_map<bool_var>& translation, ineq const& pb);
literal translate_to_sat(sat::solver& s, u_map<bool_var>& translation, ineq& a, ineq& b);
literal translate_to_sat(sat::solver& s, u_map<bool_var>& translation, literal lit);
ineq negate(ineq const& a) const;
void push_lit(literal_vector& lits, literal lit);
@ -335,7 +330,7 @@ namespace sat {
constraint* active2card();
void active2wlits();
void active2wlits(svector<wliteral>& wlits);
void justification2pb(justification const& j, literal lit, unsigned offset, ineq& p);
void justification2pb(sat::justification const& j, literal lit, unsigned offset, ineq& p);
void constraint2pb(constraint& cnstr, literal lit, unsigned offset, ineq& p);
bool validate_resolvent();
unsigned get_coeff(ineq const& pb, literal lit);
@ -346,10 +341,10 @@ namespace sat {
constraint* add_at_least(literal l, literal_vector const& lits, unsigned k, bool learned);
constraint* add_pb_ge(literal l, svector<wliteral> const& wlits, unsigned k, bool learned);
bool all_distinct(literal_vector const& lits);
bool all_distinct(clause const& c);
bool all_distinct(sat::clause const& c);
void copy_core(ba_solver* result, bool learned);
void copy_constraints(ba_solver* result, ptr_vector<constraint> const& constraints);
void copy_core(solver* result, bool learned);
void copy_constraints(solver* result, ptr_vector<constraint> const& constraints);
// Internalize
literal convert_eq_k(app* t, rational const& k, bool root, bool sign);
@ -366,23 +361,23 @@ namespace sat {
literal internalize_pb(expr* e, bool sign, bool root);
// Decompile
expr_ref get_card(std::function<expr_ref(sat::literal)>& l2e, card const& c);
expr_ref get_pb(std::function<expr_ref(sat::literal)>& l2e, pb const& p);
expr_ref get_pb(std::function<expr_ref(sat::literal)>& l2e, pbc const& p);
public:
ba_solver(euf::solver& ctx, euf::theory_id id);
ba_solver(ast_manager& m, sat::sat_internalizer& si, euf::theory_id id);
~ba_solver() override;
void set_lookahead(lookahead* l) override { m_lookahead = l; }
solver(euf::solver& ctx, euf::theory_id id);
solver(ast_manager& m, sat::sat_internalizer& si, euf::theory_id id);
~solver() override;
void set_lookahead(sat::lookahead* l) override { m_lookahead = l; }
void add_at_least(bool_var v, literal_vector const& lits, unsigned k);
void add_pb_ge(bool_var v, svector<wliteral> const& wlits, unsigned k);
bool is_external(bool_var v) override;
bool propagated(literal l, ext_constraint_idx idx) override;
bool propagated(literal l, sat::ext_constraint_idx idx) override;
bool unit_propagate() override { return false; }
lbool resolve_conflict() override;
void get_antecedents(literal l, ext_justification_idx idx, literal_vector & r, bool probing) override;
void get_antecedents(literal l, sat::ext_justification_idx idx, literal_vector & r, bool probing) override;
void asserted(literal l) override;
check_result check() override;
sat::check_result check() override;
void push() override;
void pop(unsigned n) override;
void pre_simplify() override {}
@ -392,18 +387,18 @@ namespace sat {
bool set_root(literal l, literal r) override;
void flush_roots() override;
std::ostream& display(std::ostream& out) const override;
std::ostream& display_justification(std::ostream& out, ext_justification_idx idx) const override;
std::ostream& display_constraint(std::ostream& out, ext_constraint_idx idx) const override;
std::ostream& display_justification(std::ostream& out, sat::ext_justification_idx idx) const override;
std::ostream& display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const override;
void collect_statistics(statistics& st) const override;
extension* copy(solver* s) override;
extension* copy(sat::solver* s) override;
void find_mutexes(literal_vector& lits, vector<literal_vector> & mutexes) override;
void pop_reinit() override;
void gc() override;
void gc_vars(unsigned num_vars) override;
bool is_extended_binary(ext_justification_idx idx, literal_vector & r) override;
void init_use_list(ext_use_list& ul) override;
bool is_blocked(literal l, ext_constraint_idx idx) override;
bool check_model(model const& m) const override;
bool is_extended_binary(sat::ext_justification_idx idx, literal_vector & r) override;
void init_use_list(sat::ext_use_list& ul) override;
bool is_blocked(literal l, sat::ext_constraint_idx idx) override;
bool check_model(sat::model const& m) const override;
literal internalize(expr* e, bool sign, bool root, bool redundant) override;
void internalize(expr* e, bool redundant) override;

View file

@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation
Module Name:
ba_solver_interface.h
pb_solver_interface.h
Abstract:
@ -25,7 +25,7 @@ Revision History:
#include "sat/smt/sat_smt.h"
namespace ba {
namespace pb {
typedef sat::literal literal;
typedef sat::bool_var bool_var;

View file

@ -41,7 +41,7 @@ Notes:
#include "sat/sat_cut_simplifier.h"
#include "sat/sat_drat.h"
#include "sat/tactic/goal2sat.h"
#include "sat/smt/ba_solver.h"
#include "sat/smt/pb_solver.h"
#include "sat/smt/euf_solver.h"
#include "sat/smt/sat_th.h"
#include "sat/sat_params.hpp"
@ -635,10 +635,10 @@ struct goal2sat::imp : public sat::sat_internalizer {
void convert_ba(app* t, bool root, bool sign) {
SASSERT(!m_euf);
sat::extension* ext = dynamic_cast<sat::ba_solver*>(m_solver.get_extension());
sat::extension* ext = dynamic_cast<pb::solver*>(m_solver.get_extension());
euf::th_solver* th = nullptr;
if (!ext) {
th = alloc(sat::ba_solver, m, *this, pb.get_family_id());
th = alloc(pb::solver, m, *this, pb.get_family_id());
m_solver.set_extension(th);
th->push_scopes(m_solver.num_scopes());
}
@ -1227,7 +1227,7 @@ struct sat2goal::imp {
return expr_ref(lit2expr(mc, lit), m);
};
expr_ref_vector fmls(m);
sat::ba_solver* ba = dynamic_cast<sat::ba_solver*>(ext);
pb::solver* ba = dynamic_cast<pb::solver*>(ext);
if (ba) {
ba->to_formulas(l2e, fmls);
}