mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
fixes to pb solver
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
64daa2977d
commit
133ba2d02a
|
@ -44,6 +44,18 @@ namespace datalog {
|
|||
transf.register_plugin(alloc(datalog::mk_coi_filter, ctx));
|
||||
transf.register_plugin(alloc(datalog::mk_interp_tail_simplifier, ctx));
|
||||
|
||||
if (ctx.get_params().quantify_arrays()) {
|
||||
transf.register_plugin(alloc(datalog::mk_quantifier_abstraction, ctx, 38000));
|
||||
}
|
||||
transf.register_plugin(alloc(datalog::mk_quantifier_instantiation, ctx, 37000));
|
||||
transf.register_plugin(alloc(datalog::mk_scale, ctx, 36030));
|
||||
if (ctx.get_params().magic()) {
|
||||
transf.register_plugin(alloc(datalog::mk_magic_symbolic, ctx, 36020));
|
||||
}
|
||||
transf.register_plugin(alloc(datalog::mk_karr_invariants, ctx, 36010));
|
||||
transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 36000));
|
||||
transf.register_plugin(alloc(datalog::mk_bit_blast, ctx, 35000));
|
||||
|
||||
transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 35005));
|
||||
transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 35000));
|
||||
transf.register_plugin(alloc(datalog::mk_coi_filter, ctx, 34990));
|
||||
|
@ -64,19 +76,8 @@ namespace datalog {
|
|||
transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34880));
|
||||
|
||||
|
||||
if (ctx.get_params().quantify_arrays()) {
|
||||
transf.register_plugin(alloc(datalog::mk_quantifier_abstraction, ctx, 33000));
|
||||
transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 32500));
|
||||
}
|
||||
transf.register_plugin(alloc(datalog::mk_quantifier_instantiation, ctx, 32000));
|
||||
|
||||
transf.register_plugin(alloc(datalog::mk_bit_blast, ctx, 35000));
|
||||
transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 36000));
|
||||
transf.register_plugin(alloc(datalog::mk_karr_invariants, ctx, 36010));
|
||||
if (ctx.get_params().magic()) {
|
||||
transf.register_plugin(alloc(datalog::mk_magic_symbolic, ctx, 36020));
|
||||
}
|
||||
transf.register_plugin(alloc(datalog::mk_scale, ctx, 36030));
|
||||
|
||||
ctx.transform_rules(transf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,15 +22,10 @@ Notes:
|
|||
Example:
|
||||
((_ at-most 3) x1 x1 x2 x2) == ((_ at-most 1) x1 x2)
|
||||
|
||||
- count number of clauses per cardinality constraint.
|
||||
|
||||
- TBD: when number of conflicts exceeds n^2 or n*log(n),
|
||||
- When number of conflicts exceeds n*log(n),
|
||||
then create a sorting circuit.
|
||||
where n is the arity of the cardinality constraint.
|
||||
|
||||
- TBD: do clauses get re-created? keep track of gc
|
||||
status of created clauses.
|
||||
|
||||
- TBD: add conflict resolution
|
||||
The idea is that if cardinality constraints c1, c2
|
||||
are repeatedly asserted together, then
|
||||
|
@ -38,11 +33,18 @@ Notes:
|
|||
|
||||
c1 /\ c2 -> c3
|
||||
|
||||
That is, during a propagation, assignment or conflict resolution
|
||||
step track cutting-planes.
|
||||
|
||||
- TBD: profile overhead of (re)creating sorting circuits.
|
||||
Possibly delay creating them until restart.
|
||||
|
||||
--*/
|
||||
|
||||
#include "theory_card.h"
|
||||
#include "smt_context.h"
|
||||
#include "ast_pp.h"
|
||||
#include "sorting_network.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
|
@ -78,19 +80,8 @@ namespace smt {
|
|||
SASSERT(!ctx.b_internalized(atom));
|
||||
bool_var abv = ctx.mk_bool_var(atom);
|
||||
|
||||
if (k >= static_cast<int>(num_args)) {
|
||||
bool all_pos = true;
|
||||
for (unsigned i = 0; all_pos && i < num_args; ++i) {
|
||||
all_pos = 0 < m_util.get_le_coeff(atom, i);
|
||||
}
|
||||
if (all_pos) {
|
||||
literal lit(abv);
|
||||
ctx.mk_th_axiom(get_id(), 1, &lit);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
card* c = alloc(card, abv, k);
|
||||
card* c = alloc(card, m, atom, abv, k, get_compilation_threshold(atom));
|
||||
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
expr* arg = atom->get_arg(i);
|
||||
if (!ctx.b_internalized(arg)) {
|
||||
|
@ -223,6 +214,7 @@ namespace smt {
|
|||
void theory_card::collect_statistics(::statistics& st) const {
|
||||
st.update("pb axioms", m_stats.m_num_axioms);
|
||||
st.update("pb predicates", m_stats.m_num_predicates);
|
||||
st.update("pb compilations", m_stats.m_num_compiles);
|
||||
}
|
||||
|
||||
void theory_card::reset_eh() {
|
||||
|
@ -245,14 +237,14 @@ namespace smt {
|
|||
m_stats.reset();
|
||||
}
|
||||
|
||||
void theory_card::update_min_max(bool_var v, bool is_true, card* c) {
|
||||
void theory_card::update_min_max(bool_var v, bool is_true, card& c) {
|
||||
context& ctx = get_context();
|
||||
ast_manager& m = get_manager();
|
||||
arg_t const& args = c->m_args;
|
||||
arg_t const& args = c.m_args;
|
||||
int inc = find_inc(v, args);
|
||||
int& min = c->m_current_min;
|
||||
int& max = c->m_current_max;
|
||||
int k = c->m_k;
|
||||
int& min = c.m_current_min;
|
||||
int& max = c.m_current_max;
|
||||
int k = c.m_k;
|
||||
// inc > 0 & is_true -> min += inc
|
||||
// inc < 0 & is_true -> max += inc
|
||||
// inc > 0 & !is_true -> max -= inc
|
||||
|
@ -278,7 +270,7 @@ namespace smt {
|
|||
SASSERT(min <= max);
|
||||
}
|
||||
|
||||
void theory_card::assign_use(bool_var v, bool is_true, card* c) {
|
||||
void theory_card::assign_use(bool_var v, bool is_true, card& c) {
|
||||
update_min_max(v, is_true, c);
|
||||
propagate_assignment(c);
|
||||
}
|
||||
|
@ -307,11 +299,11 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
int theory_card::accumulate_min(literal_vector& lits, card* c) {
|
||||
int theory_card::accumulate_min(literal_vector& lits, card& c) {
|
||||
context& ctx = get_context();
|
||||
int k = c->m_k;
|
||||
arg_t const& args = c->m_args;
|
||||
int curr_min = c->m_abs_min;
|
||||
int k = c.m_k;
|
||||
arg_t const& args = c.m_args;
|
||||
int curr_min = c.m_abs_min;
|
||||
for (unsigned i = 0; i < args.size() && curr_min <= k; ++i) {
|
||||
bool_var bv = args[i].first;
|
||||
int inc = args[i].second;
|
||||
|
@ -324,11 +316,11 @@ namespace smt {
|
|||
return curr_min;
|
||||
}
|
||||
|
||||
int theory_card::accumulate_max(literal_vector& lits, card* c) {
|
||||
int theory_card::accumulate_max(literal_vector& lits, card& c) {
|
||||
context& ctx = get_context();
|
||||
arg_t const& args = c->m_args;
|
||||
int k = c->m_k;
|
||||
int curr_max = c->m_abs_max;
|
||||
arg_t const& args = c.m_args;
|
||||
int k = c.m_k;
|
||||
int curr_max = c.m_abs_max;
|
||||
for (unsigned i = 0; i < args.size() && k < curr_max; ++i) {
|
||||
bool_var bv = args[i].first;
|
||||
int inc = args[i].second;
|
||||
|
@ -341,19 +333,33 @@ namespace smt {
|
|||
return curr_max;
|
||||
}
|
||||
|
||||
void theory_card::propagate_assignment(card* c) {
|
||||
void theory_card::propagate_assignment(card& c) {
|
||||
if (c.m_compiled) {
|
||||
return;
|
||||
}
|
||||
if (should_compile(c)) {
|
||||
compile_at_most(c);
|
||||
return;
|
||||
}
|
||||
context& ctx = get_context();
|
||||
arg_t const& args = c->m_args;
|
||||
bool_var abv = c->m_bv;
|
||||
int min = c->m_current_min;
|
||||
int max = c->m_current_max;
|
||||
int k = c->m_k;
|
||||
ast_manager& m = get_manager();
|
||||
arg_t const& args = c.m_args;
|
||||
bool_var abv = c.m_bv;
|
||||
int min = c.m_current_min;
|
||||
int max = c.m_current_max;
|
||||
int k = c.m_k;
|
||||
|
||||
TRACE("card",
|
||||
tout << mk_pp(c.m_app, m) << " min: "
|
||||
<< min << " max: " << max << "\n";);
|
||||
|
||||
//
|
||||
// if min > k && abv != l_false -> force abv false
|
||||
// if max <= k && abv != l_true -> force abv true
|
||||
// if min == k && abv == l_true -> force positive unassigned literals false
|
||||
// if max == k + 1 && abv == l_false -> force negative unassigned literals false
|
||||
// if min == k && abv == l_true -> force positive
|
||||
// unassigned literals false
|
||||
// if max == k + 1 && abv == l_false -> force negative
|
||||
// unassigned literals false
|
||||
//
|
||||
lbool aval = ctx.get_assignment(abv);
|
||||
if (min > k && aval != l_false) {
|
||||
|
@ -361,21 +367,21 @@ namespace smt {
|
|||
lits.push_back(~literal(abv));
|
||||
int curr_min = accumulate_min(lits, c);
|
||||
SASSERT(curr_min > k);
|
||||
add_clause(lits);
|
||||
add_clause(c, lits);
|
||||
}
|
||||
else if (max <= k && aval != l_true) {
|
||||
literal_vector& lits = get_lits();
|
||||
lits.push_back(literal(abv));
|
||||
int curr_max = accumulate_max(lits, c);
|
||||
SASSERT(curr_max <= k);
|
||||
add_clause(lits);
|
||||
add_clause(c, lits);
|
||||
}
|
||||
else if (min == k && aval == l_true) {
|
||||
literal_vector& lits = get_lits();
|
||||
lits.push_back(~literal(abv));
|
||||
int curr_min = accumulate_min(lits, c);
|
||||
if (curr_min > k) {
|
||||
add_clause(lits);
|
||||
add_clause(c, lits);
|
||||
}
|
||||
else {
|
||||
SASSERT(curr_min == k);
|
||||
|
@ -383,9 +389,9 @@ namespace smt {
|
|||
bool_var bv = args[i].first;
|
||||
int inc = args[i].second;
|
||||
if (inc_min(inc, ctx.get_assignment(bv)) == l_undef) {
|
||||
lits.push_back(literal(bv, inc > 0)); // avoid incrementing min.
|
||||
add_clause(lits);
|
||||
lits.pop_back();
|
||||
literal_vector lits_save(lits); // add_clause has a side-effect on literals.
|
||||
lits_save.push_back(literal(bv, inc > 0)); // avoid incrementing min.
|
||||
add_clause(c, lits_save);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,16 +401,16 @@ namespace smt {
|
|||
lits.push_back(literal(abv));
|
||||
int curr_max = accumulate_max(lits, c);
|
||||
if (curr_max <= k) {
|
||||
add_clause(lits);
|
||||
add_clause(c, lits);
|
||||
}
|
||||
else if (curr_max == k + 1) {
|
||||
for (unsigned i = 0; i < args.size(); ++i) {
|
||||
bool_var bv = args[i].first;
|
||||
int inc = args[i].second;
|
||||
if (dec_max(inc, ctx.get_assignment(bv)) == l_undef) {
|
||||
lits.push_back(literal(bv, inc < 0)); // avoid decrementing max.
|
||||
add_clause(lits);
|
||||
lits.pop_back();
|
||||
literal_vector lits_save(lits); // add_clause has a side-effect on literals.
|
||||
lits_save.push_back(literal(bv, inc < 0)); // avoid decrementing max.
|
||||
add_clause(c, lits_save);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -420,11 +426,11 @@ namespace smt {
|
|||
|
||||
if (m_watch.find(v, cards)) {
|
||||
for (unsigned i = 0; i < cards->size(); ++i) {
|
||||
assign_use(v, is_true, (*cards)[i]);
|
||||
assign_use(v, is_true, *(*cards)[i]);
|
||||
}
|
||||
}
|
||||
if (m_cards.find(v, c)) {
|
||||
propagate_assignment(c);
|
||||
propagate_assignment(*c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +455,203 @@ namespace smt {
|
|||
return vars[mid].second;
|
||||
}
|
||||
|
||||
struct theory_card::sort_expr {
|
||||
theory_card& th;
|
||||
context& ctx;
|
||||
ast_manager& m;
|
||||
expr_ref_vector m_trail;
|
||||
sort_expr(theory_card& th):
|
||||
th(th),
|
||||
ctx(th.get_context()),
|
||||
m(th.get_manager()),
|
||||
m_trail(m) {}
|
||||
typedef expr* T;
|
||||
typedef expr_ref_vector vector;
|
||||
|
||||
T mk_ite(T a, T b, T c) {
|
||||
if (m.is_true(a)) {
|
||||
return b;
|
||||
}
|
||||
if (m.is_false(a)) {
|
||||
return c;
|
||||
}
|
||||
if (b == c) {
|
||||
return b;
|
||||
}
|
||||
m_trail.push_back(m.mk_ite(a, b, c));
|
||||
return m_trail.back();
|
||||
}
|
||||
|
||||
T mk_le(T a, T b) {
|
||||
return mk_ite(b, a, m.mk_true());
|
||||
}
|
||||
|
||||
T mk_default() {
|
||||
return m.mk_false();
|
||||
}
|
||||
|
||||
literal internalize(card& ca, expr* e) {
|
||||
obj_map<expr, literal> cache;
|
||||
for (unsigned i = 0; i < ca.m_args.size(); ++i) {
|
||||
cache.insert(ca.m_app->get_arg(i), literal(ca.m_args[i].first));
|
||||
}
|
||||
cache.insert(m.mk_false(), false_literal);
|
||||
cache.insert(m.mk_true(), true_literal);
|
||||
ptr_vector<expr> todo;
|
||||
todo.push_back(e);
|
||||
expr *a, *b, *c;
|
||||
literal la, lb, lc;
|
||||
while (!todo.empty()) {
|
||||
expr* t = todo.back();
|
||||
if (cache.contains(t)) {
|
||||
todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
VERIFY(m.is_ite(t, a, b, c));
|
||||
unsigned sz = todo.size();
|
||||
if (!cache.find(a, la)) {
|
||||
todo.push_back(a);
|
||||
}
|
||||
if (!cache.find(b, lb)) {
|
||||
todo.push_back(b);
|
||||
}
|
||||
if (!cache.find(c, lc)) {
|
||||
todo.push_back(c);
|
||||
}
|
||||
if (sz != todo.size()) {
|
||||
continue;
|
||||
}
|
||||
todo.pop_back();
|
||||
cache.insert(t, mk_ite(ca, t, la, lb, lc));
|
||||
}
|
||||
return cache.find(e);
|
||||
}
|
||||
|
||||
literal mk_ite(card& ca, expr* t, literal a, literal b, literal c) {
|
||||
if (a == true_literal) {
|
||||
return b;
|
||||
}
|
||||
else if (a == false_literal) {
|
||||
return c;
|
||||
}
|
||||
else if (b == true_literal && c == false_literal) {
|
||||
return a;
|
||||
}
|
||||
else if (b == false_literal && c == true_literal) {
|
||||
return ~a;
|
||||
}
|
||||
else if (b == c) {
|
||||
return b;
|
||||
}
|
||||
else {
|
||||
expr_ref p(m);
|
||||
expr* r;
|
||||
if (ca.m_replay.find(t, r)) {
|
||||
p = r;
|
||||
}
|
||||
else {
|
||||
p = m.mk_fresh_const("s", m.mk_bool_sort());
|
||||
ca.m_replay.insert(t, p);
|
||||
ca.m_trail.push_back(p);
|
||||
}
|
||||
literal l;
|
||||
if (ctx.b_internalized(p)) {
|
||||
l = literal(ctx.get_bool_var(p));
|
||||
}
|
||||
else {
|
||||
l = literal(ctx.mk_bool_var(p));
|
||||
}
|
||||
add_clause(~l, ~a, b);
|
||||
add_clause(~l, a, c);
|
||||
add_clause(l, ~a, ~b);
|
||||
add_clause(l, a, ~c);
|
||||
TRACE("card", tout << p << " ::= (if ";
|
||||
ctx.display_detailed_literal(tout, a);
|
||||
ctx.display_detailed_literal(tout << " ", b);
|
||||
ctx.display_detailed_literal(tout << " ", c);
|
||||
tout << ")\n";);
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// auxiliary clauses don't get garbage collected.
|
||||
void add_clause(literal a, literal b, literal c) {
|
||||
literal_vector& lits = th.get_lits();
|
||||
if (a != null_literal) lits.push_back(a);
|
||||
if (b != null_literal) lits.push_back(b);
|
||||
if (c != null_literal) lits.push_back(c);
|
||||
justification* js = 0;
|
||||
TRACE("card",
|
||||
ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
ctx.mk_clause(lits.size(), lits.c_ptr(), js, CLS_AUX, 0);
|
||||
}
|
||||
|
||||
void add_clause(literal l1, literal l2) {
|
||||
add_clause(l1, l2, null_literal);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
unsigned theory_card::get_compilation_threshold(app* a) {
|
||||
if (!m_util.is_at_most_k(a)) {
|
||||
return UINT_MAX;
|
||||
}
|
||||
unsigned num_args = a->get_num_args();
|
||||
unsigned log = 1, n = 1;
|
||||
while (n <= num_args) {
|
||||
++log;
|
||||
n *= 2;
|
||||
}
|
||||
TRACE("card", tout << "threshold:" << (num_args*log) << "\n";);
|
||||
return num_args*log;
|
||||
}
|
||||
|
||||
bool theory_card::should_compile(card& c) {
|
||||
if (!m_util.is_at_most_k(c.m_app)) {
|
||||
return false;
|
||||
}
|
||||
return c.m_num_propagations >= c.m_compilation_threshold;
|
||||
}
|
||||
|
||||
void theory_card::compile_at_most(card& c) {
|
||||
++m_stats.m_num_compiles;
|
||||
ast_manager& m = get_manager();
|
||||
context& ctx = get_context();
|
||||
app* a = c.m_app;
|
||||
SASSERT(m_util.is_at_most_k(a));
|
||||
literal atmostk;
|
||||
int k = m_util.get_k(a);
|
||||
unsigned num_args = a->get_num_args();
|
||||
|
||||
sort_expr se(*this);
|
||||
if (k >= static_cast<int>(num_args)) {
|
||||
atmostk = true_literal;
|
||||
}
|
||||
else if (k < 0) {
|
||||
atmostk = false_literal;
|
||||
}
|
||||
else {
|
||||
sorting_network<sort_expr> sn(se);
|
||||
expr_ref_vector in(m), out(m);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
in.push_back(c.m_app->get_arg(i));
|
||||
}
|
||||
sn(in, out);
|
||||
atmostk = ~se.internalize(c, out[k].get()); // k'th output is 0.
|
||||
TRACE("card", tout << "~atmost: " << mk_pp(out[k].get(), m) << "\n";);
|
||||
}
|
||||
literal thl = literal(c.m_bv);
|
||||
se.add_clause(~thl, atmostk);
|
||||
se.add_clause(thl, ~atmostk);
|
||||
TRACE("card", tout << mk_pp(a, m) << "\n";);
|
||||
// auxiliary clauses get removed when popping scopes.
|
||||
// we have to recompile the circuit after back-tracking.
|
||||
ctx.push_trail(value_trail<context, bool>(c.m_compiled));
|
||||
c.m_compiled = true;
|
||||
}
|
||||
|
||||
|
||||
void theory_card::init_search_eh() {
|
||||
|
||||
}
|
||||
|
@ -483,16 +686,14 @@ namespace smt {
|
|||
return m_literals;
|
||||
}
|
||||
|
||||
void theory_card::add_clause(literal_vector const& lits) {
|
||||
void theory_card::add_clause(card& c, literal_vector const& lits) {
|
||||
++c.m_num_propagations;
|
||||
m_stats.m_num_axioms++;
|
||||
context& ctx = get_context();
|
||||
TRACE("card", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
TRACE("card", tout << "#prop:" << c.m_num_propagations << " - "; ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
justification* js = 0;
|
||||
ctx.mk_clause(lits.size(), lits.c_ptr(), js, CLS_AUX_LEMMA, 0);
|
||||
IF_VERBOSE(1,
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
verbose_stream() << lits[i] << " ";
|
||||
}
|
||||
IF_VERBOSE(1, ctx.display_literals_verbose(verbose_stream(), lits.size(), lits.c_ptr());
|
||||
verbose_stream() << "\n";);
|
||||
// ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
|
||||
}
|
||||
|
|
|
@ -22,20 +22,25 @@ Notes:
|
|||
|
||||
#include "smt_theory.h"
|
||||
#include "card_decl_plugin.h"
|
||||
#include "smt_clause.h"
|
||||
|
||||
namespace smt {
|
||||
class theory_card : public theory {
|
||||
|
||||
struct sort_expr;
|
||||
typedef svector<std::pair<bool_var, int> > arg_t;
|
||||
|
||||
struct stats {
|
||||
unsigned m_num_axioms;
|
||||
unsigned m_num_predicates;
|
||||
unsigned m_num_compiles;
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
stats() { reset(); }
|
||||
};
|
||||
|
||||
|
||||
struct card {
|
||||
app* m_app;
|
||||
int m_k;
|
||||
bool_var m_bv;
|
||||
int m_current_min;
|
||||
|
@ -43,9 +48,17 @@ namespace smt {
|
|||
int m_abs_min;
|
||||
int m_abs_max;
|
||||
arg_t m_args;
|
||||
card(bool_var bv, int k):
|
||||
m_k(k), m_bv(bv)
|
||||
{}
|
||||
unsigned m_num_propagations;
|
||||
unsigned m_compilation_threshold;
|
||||
bool m_compiled;
|
||||
obj_map<expr, expr*> m_replay;
|
||||
expr_ref_vector m_trail;
|
||||
card(ast_manager& m, app* a, bool_var bv, int k, unsigned threshold):
|
||||
m_app(a), m_k(k), m_bv(bv),
|
||||
m_num_propagations(0), m_compilation_threshold(threshold), m_compiled(false),
|
||||
m_trail(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
u_map<ptr_vector<card>*> m_watch; // use-list of literals.
|
||||
|
@ -61,18 +74,22 @@ namespace smt {
|
|||
void add_watch(bool_var bv, card* c);
|
||||
void add_card(card* c);
|
||||
|
||||
void add_clause(literal_vector const& lits);
|
||||
void add_clause(card& c, literal_vector const& lits);
|
||||
literal_vector& get_lits();
|
||||
|
||||
int find_inc(bool_var bv, svector<std::pair<bool_var, int> >const& vars);
|
||||
void theory_card::propagate_assignment(card* c);
|
||||
int theory_card::accumulate_max(literal_vector& lits, card* c);
|
||||
int theory_card::accumulate_min(literal_vector& lits, card* c);
|
||||
lbool theory_card::dec_max(int inc, lbool val);
|
||||
lbool theory_card::inc_min(int inc, lbool val);
|
||||
void theory_card::assign_use(bool_var v, bool is_true, card* c);
|
||||
void theory_card::update_min_max(bool_var v, bool is_true, card* c);
|
||||
|
||||
int find_inc(bool_var bv, svector<std::pair<bool_var, int> >const& vars);
|
||||
void propagate_assignment(card& c);
|
||||
int accumulate_max(literal_vector& lits, card& c);
|
||||
int accumulate_min(literal_vector& lits, card& c);
|
||||
lbool dec_max(int inc, lbool val);
|
||||
lbool inc_min(int inc, lbool val);
|
||||
void assign_use(bool_var v, bool is_true, card& c);
|
||||
void update_min_max(bool_var v, bool is_true, card& c);
|
||||
|
||||
void compile_at_most(card& c);
|
||||
expr_ref nnf(expr* e);
|
||||
bool should_compile(card& c);
|
||||
unsigned get_compilation_threshold(app* atom);
|
||||
public:
|
||||
theory_card(ast_manager& m);
|
||||
|
||||
|
|
Loading…
Reference in a new issue