mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 02:15:19 +00:00
prep for pragmas
This commit is contained in:
parent
6670cf0b65
commit
dcc01b874a
|
@ -112,6 +112,27 @@ static void read_clause(Buffer & in, std::ostream& err, sat::literal_vector & li
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Buffer>
|
||||
static void read_pragma(Buffer & in, std::ostream& err, std::string& p) {
|
||||
skip_whitespace(in);
|
||||
if (*in != 'p')
|
||||
return;
|
||||
++in;
|
||||
while (*in == ' ')
|
||||
++in;
|
||||
while (true) {
|
||||
if (*in == EOF)
|
||||
return;
|
||||
if (*in == '\n') {
|
||||
++in;
|
||||
return;
|
||||
}
|
||||
p.push_back(*in);
|
||||
++in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Buffer>
|
||||
static bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solver) {
|
||||
sat::literal_vector lits;
|
||||
|
@ -156,7 +177,9 @@ namespace dimacs {
|
|||
sat::status_pp pp(r.m_status, p.th);
|
||||
switch (r.m_tag) {
|
||||
case drat_record::tag_t::is_clause:
|
||||
return out << pp << " " << r.m_lits << " 0\n";
|
||||
if (!r.m_pragma.empty())
|
||||
return out << pp << " " << r.m_lits << " 0 p " << r.m_pragma << "\n";
|
||||
return out << pp << " " << r.m_lits << " 0\n";
|
||||
case drat_record::tag_t::is_node:
|
||||
return out << "e " << r.m_node_id << " " << r.m_name << " " << r.m_args << "0\n";
|
||||
case drat_record::tag_t::is_sort:
|
||||
|
@ -280,6 +303,7 @@ namespace dimacs {
|
|||
try {
|
||||
loop:
|
||||
skip_whitespace(in);
|
||||
m_record.m_pragma.clear();
|
||||
switch (*in) {
|
||||
case EOF:
|
||||
return false;
|
||||
|
@ -304,6 +328,7 @@ namespace dimacs {
|
|||
theory_id = read_theory_id();
|
||||
skip_whitespace(in);
|
||||
read_clause(in, err, m_record.m_lits);
|
||||
read_pragma(in, err, m_record.m_pragma);
|
||||
m_record.m_tag = drat_record::tag_t::is_clause;
|
||||
m_record.m_status = sat::status::th(false, theory_id);
|
||||
break;
|
||||
|
|
|
@ -59,10 +59,11 @@ namespace dimacs {
|
|||
// a node populates m_node_id, m_name, m_args
|
||||
// a bool def populates m_node_id and one element in m_args
|
||||
sat::literal_vector m_lits;
|
||||
sat::status m_status{ sat::status::redundant() };
|
||||
unsigned m_node_id{ 0 };
|
||||
sat::status m_status = sat::status::redundant();
|
||||
unsigned m_node_id = 0;
|
||||
std::string m_name;
|
||||
unsigned_vector m_args;
|
||||
std::string m_pragma;
|
||||
};
|
||||
|
||||
struct drat_pp {
|
||||
|
|
|
@ -137,6 +137,14 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
buffer[len++] = '0';
|
||||
if (st.get_pragma()) {
|
||||
buffer[len++] = ' ';
|
||||
buffer[len++] = 'p';
|
||||
buffer[len++] = ' ';
|
||||
char const* ps = st.get_pragma();
|
||||
while (*ps)
|
||||
buffer[len++] = *ps++;
|
||||
}
|
||||
buffer[len++] = '\n';
|
||||
m_out->write(buffer, len);
|
||||
|
||||
|
|
|
@ -98,22 +98,24 @@ namespace sat {
|
|||
enum class st { input, asserted, redundant, deleted };
|
||||
st m_st;
|
||||
int m_orig;
|
||||
char const* m_pragma;
|
||||
public:
|
||||
status(st s, int o) : m_st(s), m_orig(o) {};
|
||||
status(status const& s) : m_st(s.m_st), m_orig(s.m_orig) {}
|
||||
status(status&& s) noexcept { m_st = st::asserted; m_orig = -1; std::swap(m_st, s.m_st); std::swap(m_orig, s.m_orig); }
|
||||
status(st s, int o, char const* ps = nullptr) : m_st(s), m_orig(o), m_pragma(ps) {};
|
||||
status(status const& s) : m_st(s.m_st), m_orig(s.m_orig), m_pragma(s.m_pragma) {}
|
||||
status(status&& s) noexcept { m_st = st::asserted; m_orig = -1; std::swap(m_st, s.m_st); std::swap(m_orig, s.m_orig); std::swap(m_pragma, s.m_pragma); }
|
||||
status& operator=(status const& other) { m_st = other.m_st; m_orig = other.m_orig; return *this; }
|
||||
static status redundant() { return status(status::st::redundant, -1); }
|
||||
static status asserted() { return status(status::st::asserted, -1); }
|
||||
static status deleted() { return status(status::st::deleted, -1); }
|
||||
static status input() { return status(status::st::input, -1); }
|
||||
|
||||
static status th(bool redundant, int id) { return status(redundant ? st::redundant : st::asserted, id); }
|
||||
static status th(bool redundant, int id, char const* ps = nullptr) { return status(redundant ? st::redundant : st::asserted, id, ps); }
|
||||
|
||||
bool is_input() const { return st::input == m_st; }
|
||||
bool is_redundant() const { return st::redundant == m_st; }
|
||||
bool is_asserted() const { return st::asserted == m_st; }
|
||||
bool is_deleted() const { return st::deleted == m_st; }
|
||||
char const* get_pragma() const { return m_pragma; }
|
||||
|
||||
bool is_sat() const { return -1 == m_orig; }
|
||||
int get_th() const { return m_orig; }
|
||||
|
|
|
@ -233,45 +233,46 @@ namespace arith {
|
|||
SASSERT(b1.get_var() == b2.get_var());
|
||||
if (k1 == k2 && kind1 == kind2) return;
|
||||
SASSERT(k1 != k2 || kind1 != kind2);
|
||||
char const* bound_params = "farkas 1 1";
|
||||
|
||||
if (kind1 == lp_api::lower_t) {
|
||||
if (kind2 == lp_api::lower_t) {
|
||||
if (k2 <= k1)
|
||||
add_clause(~l1, l2);
|
||||
add_clause(~l1, l2, bound_params);
|
||||
else
|
||||
add_clause(l1, ~l2);
|
||||
add_clause(l1, ~l2, bound_params);
|
||||
}
|
||||
else if (k1 <= k2)
|
||||
// k1 <= k2, k1 <= x or x <= k2
|
||||
add_clause(l1, l2);
|
||||
else {
|
||||
// k1 > hi_inf, k1 <= x => ~(x <= hi_inf)
|
||||
add_clause(~l1, ~l2);
|
||||
add_clause(~l1, ~l2, bound_params);
|
||||
if (v_is_int && k1 == k2 + rational(1))
|
||||
// k1 <= x or x <= k1-1
|
||||
add_clause(l1, l2);
|
||||
add_clause(l1, l2, bound_params);
|
||||
}
|
||||
}
|
||||
else if (kind2 == lp_api::lower_t) {
|
||||
if (k1 >= k2)
|
||||
// k1 >= lo_inf, k1 >= x or lo_inf <= x
|
||||
add_clause(l1, l2);
|
||||
add_clause(l1, l2, bound_params);
|
||||
else {
|
||||
// k1 < k2, k2 <= x => ~(x <= k1)
|
||||
add_clause(~l1, ~l2);
|
||||
add_clause(~l1, ~l2, bound_params);
|
||||
if (v_is_int && k1 == k2 - rational(1))
|
||||
// x <= k1 or k1+l <= x
|
||||
add_clause(l1, l2);
|
||||
add_clause(l1, l2, bound_params);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// kind1 == A_UPPER, kind2 == A_UPPER
|
||||
if (k1 >= k2)
|
||||
// k1 >= k2, x <= k2 => x <= k1
|
||||
add_clause(l1, ~l2);
|
||||
add_clause(l1, ~l2, bound_params);
|
||||
else
|
||||
// k1 <= hi_sup , x <= k1 => x <= hi_sup
|
||||
add_clause(~l1, l2);
|
||||
add_clause(~l1, l2, bound_params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -498,8 +499,8 @@ namespace arith {
|
|||
if (x->get_root() == y->get_root())
|
||||
return;
|
||||
reset_evidence();
|
||||
set_evidence(ci1, m_core, m_eqs);
|
||||
set_evidence(ci2, m_core, m_eqs);
|
||||
set_evidence(ci1);
|
||||
set_evidence(ci2);
|
||||
++m_stats.m_fixed_eqs;
|
||||
auto* jst = euf::th_explain::propagate(*this, m_core, m_eqs, x, y);
|
||||
ctx.propagate(x, y, jst->to_index());
|
||||
|
|
|
@ -194,11 +194,8 @@ namespace arith {
|
|||
++m_stats.m_bound_propagations2;
|
||||
reset_evidence();
|
||||
m_core.push_back(lit1);
|
||||
m_params.push_back(parameter(m_farkas));
|
||||
m_params.push_back(parameter(rational(1)));
|
||||
m_params.push_back(parameter(rational(1)));
|
||||
TRACE("arith", tout << lit2 << " <- " << m_core << "\n";);
|
||||
assign(lit2, m_core, m_eqs, m_params);
|
||||
assign(lit2, m_core, m_eqs, "farkas 1 1");
|
||||
++m_stats.m_bounds_propagations;
|
||||
}
|
||||
|
||||
|
@ -239,13 +236,11 @@ namespace arith {
|
|||
bool first = true;
|
||||
for (unsigned i = 0; i < bounds.size(); ++i) {
|
||||
api_bound* b = bounds[i];
|
||||
if (s().value(b->get_lit()) != l_undef) {
|
||||
if (s().value(b->get_lit()) != l_undef)
|
||||
continue;
|
||||
}
|
||||
literal lit = is_bound_implied(be.kind(), be.m_bound, *b);
|
||||
if (lit == sat::null_literal) {
|
||||
if (lit == sat::null_literal)
|
||||
continue;
|
||||
}
|
||||
TRACE("arith", tout << lit << " bound: " << *b << " first: " << first << "\n";);
|
||||
|
||||
lp().settings().stats().m_num_of_implied_bounds++;
|
||||
|
@ -260,7 +255,7 @@ namespace arith {
|
|||
TRACE("arith", for (auto lit : m_core) tout << lit << ": " << s().value(lit) << "\n";);
|
||||
DEBUG_CODE(for (auto lit : m_core) { VERIFY(s().value(lit) == l_true); });
|
||||
++m_stats.m_bound_propagations1;
|
||||
assign(lit, m_core, m_eqs, m_params);
|
||||
assign(lit, m_core, m_eqs, "bounds");
|
||||
}
|
||||
|
||||
if (should_refine_bounds() && first)
|
||||
|
@ -297,7 +292,7 @@ namespace arith {
|
|||
|
||||
|
||||
void solver::consume(rational const& v, lp::constraint_index j) {
|
||||
set_evidence(j, m_core, m_eqs);
|
||||
set_evidence(j);
|
||||
m_explanation.add_pair(j, v);
|
||||
}
|
||||
|
||||
|
@ -318,7 +313,7 @@ namespace arith {
|
|||
return false;
|
||||
reset_evidence();
|
||||
for (auto ev : e)
|
||||
set_evidence(ev.ci(), m_core, m_eqs);
|
||||
set_evidence(ev.ci());
|
||||
auto* jst = euf::th_explain::propagate(*this, m_core, m_eqs, n1, n2);
|
||||
ctx.propagate(n1, n2, jst->to_index());
|
||||
return true;
|
||||
|
@ -375,7 +370,7 @@ namespace arith {
|
|||
reset_evidence();
|
||||
m_explanation.clear();
|
||||
lp().explain_implied_bound(be, m_bp);
|
||||
assign(bound, m_core, m_eqs, m_params);
|
||||
assign(bound, m_core, m_eqs, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -748,10 +743,10 @@ namespace arith {
|
|||
|
||||
++m_stats.m_fixed_eqs;
|
||||
reset_evidence();
|
||||
set_evidence(ci1, m_core, m_eqs);
|
||||
set_evidence(ci2, m_core, m_eqs);
|
||||
set_evidence(ci3, m_core, m_eqs);
|
||||
set_evidence(ci4, m_core, m_eqs);
|
||||
set_evidence(ci1);
|
||||
set_evidence(ci2);
|
||||
set_evidence(ci3);
|
||||
set_evidence(ci4);
|
||||
enode* x = var2enode(v1);
|
||||
enode* y = var2enode(v2);
|
||||
auto* jst = euf::th_explain::propagate(*this, m_core, m_eqs, x, y);
|
||||
|
@ -1161,13 +1156,13 @@ namespace arith {
|
|||
// m_explanation implies term <= k
|
||||
reset_evidence();
|
||||
for (auto ev : m_explanation)
|
||||
set_evidence(ev.ci(), m_core, m_eqs);
|
||||
set_evidence(ev.ci());
|
||||
// The call mk_bound() can set the m_infeasible_column in lar_solver
|
||||
// so the explanation is safer to take before this call.
|
||||
app_ref b = mk_bound(m_lia->get_term(), m_lia->get_offset(), !m_lia->is_upper());
|
||||
IF_VERBOSE(4, verbose_stream() << "cut " << b << "\n");
|
||||
literal lit = expr2literal(b);
|
||||
assign(lit, m_core, m_eqs, m_params);
|
||||
assign(lit, m_core, m_eqs, nullptr);
|
||||
lia_check = l_false;
|
||||
break;
|
||||
}
|
||||
|
@ -1189,20 +1184,16 @@ namespace arith {
|
|||
return lia_check;
|
||||
}
|
||||
|
||||
void solver::assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs, vector<parameter> const& params) {
|
||||
std::cout << "assign: ";
|
||||
for (auto const& p : params)
|
||||
std::cout << p << " ";
|
||||
std::cout << "\n";
|
||||
void solver::assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs, char const* pma) {
|
||||
if (core.size() < small_lemma_size() && eqs.empty()) {
|
||||
m_core2.reset();
|
||||
for (auto const& c : core)
|
||||
m_core2.push_back(~c);
|
||||
m_core2.push_back(lit);
|
||||
add_clause(m_core2);
|
||||
add_clause(m_core2, pma);
|
||||
}
|
||||
else {
|
||||
auto* jst = euf::th_explain::propagate(*this, core, eqs, lit);
|
||||
auto* jst = euf::th_explain::propagate(*this, core, eqs, lit, pma);
|
||||
ctx.propagate(lit, jst->to_index());
|
||||
}
|
||||
}
|
||||
|
@ -1225,7 +1216,7 @@ namespace arith {
|
|||
++m_num_conflicts;
|
||||
++m_stats.m_conflicts;
|
||||
for (auto ev : m_explanation)
|
||||
set_evidence(ev.ci(), m_core, m_eqs);
|
||||
set_evidence(ev.ci());
|
||||
TRACE("arith",
|
||||
tout << "Lemma - " << (is_conflict ? "conflict" : "propagation") << "\n";
|
||||
for (literal c : m_core) tout << literal2expr(c) << "\n";
|
||||
|
@ -1247,7 +1238,7 @@ namespace arith {
|
|||
return lp().get_status() == lp::lp_status::INFEASIBLE;
|
||||
}
|
||||
|
||||
void solver::set_evidence(lp::constraint_index idx, literal_vector& core, svector<enode_pair>& eqs) {
|
||||
void solver::set_evidence(lp::constraint_index idx) {
|
||||
if (idx == UINT_MAX) {
|
||||
return;
|
||||
}
|
||||
|
@ -1255,7 +1246,7 @@ namespace arith {
|
|||
case inequality_source: {
|
||||
literal lit = m_inequalities[idx];
|
||||
SASSERT(lit != sat::null_literal);
|
||||
core.push_back(lit);
|
||||
m_core.push_back(lit);
|
||||
break;
|
||||
}
|
||||
case equality_source:
|
||||
|
|
|
@ -413,8 +413,8 @@ namespace arith {
|
|||
void get_infeasibility_explanation_and_set_conflict();
|
||||
void set_conflict();
|
||||
void set_conflict_or_lemma(literal_vector const& core, bool is_conflict);
|
||||
void set_evidence(lp::constraint_index idx, literal_vector& core, svector<enode_pair>& eqs);
|
||||
void assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs, vector<parameter> const& params);
|
||||
void set_evidence(lp::constraint_index idx);
|
||||
void assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs, char const* pma);
|
||||
|
||||
void false_case_of_check_nla(const nla::lemma& l);
|
||||
void dbg_finalize_model(model& mdl);
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace euf {
|
|||
lits.push_back(jst.lit_consequent());
|
||||
if (jst.eq_consequent().first != nullptr)
|
||||
lits.push_back(add_lit(jst.eq_consequent()));
|
||||
get_drat().add(lits, sat::status::th(m_is_redundant, jst.ext().get_id()));
|
||||
get_drat().add(lits, sat::status::th(m_is_redundant, jst.ext().get_id(), jst.get_pragma()));
|
||||
}
|
||||
|
||||
void solver::drat_eq_def(literal lit, expr* eq) {
|
||||
|
|
|
@ -125,8 +125,8 @@ namespace euf {
|
|||
pop_core(n);
|
||||
}
|
||||
|
||||
sat::status th_euf_solver::mk_status() {
|
||||
return sat::status::th(m_is_redundant, get_id());
|
||||
sat::status th_euf_solver::mk_status(char const* ps) {
|
||||
return sat::status::th(m_is_redundant, get_id(), ps);
|
||||
}
|
||||
|
||||
bool th_euf_solver::add_unit(sat::literal lit) {
|
||||
|
@ -149,6 +149,11 @@ namespace euf {
|
|||
return add_clause(2, lits);
|
||||
}
|
||||
|
||||
bool th_euf_solver::add_clause(sat::literal a, sat::literal b, char const* ps) {
|
||||
sat::literal lits[2] = { a, b };
|
||||
return add_clause(2, lits, ps);
|
||||
}
|
||||
|
||||
bool th_euf_solver::add_clause(sat::literal a, sat::literal b, sat::literal c) {
|
||||
sat::literal lits[3] = { a, b, c };
|
||||
return add_clause(3, lits);
|
||||
|
@ -159,12 +164,12 @@ namespace euf {
|
|||
return add_clause(4, lits);
|
||||
}
|
||||
|
||||
bool th_euf_solver::add_clause(unsigned n, sat::literal* lits) {
|
||||
bool th_euf_solver::add_clause(unsigned n, sat::literal* lits, char const* ps) {
|
||||
bool was_true = false;
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
was_true |= is_true(lits[i]);
|
||||
ctx.add_root(n, lits);
|
||||
s().add_clause(n, lits, mk_status());
|
||||
s().add_clause(n, lits, mk_status(ps));
|
||||
return !was_true;
|
||||
}
|
||||
|
||||
|
@ -221,37 +226,44 @@ namespace euf {
|
|||
return ctx.s().rand()();
|
||||
}
|
||||
|
||||
size_t th_explain::get_obj_size(unsigned num_lits, unsigned num_eqs) {
|
||||
return sat::constraint_base::obj_size(sizeof(th_explain) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs);
|
||||
size_t th_explain::get_obj_size(unsigned num_lits, unsigned num_eqs, char const* pma) {
|
||||
return sat::constraint_base::obj_size(sizeof(th_explain) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs + (pma?strlen(pma)+1:1));
|
||||
}
|
||||
|
||||
th_explain::th_explain(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode_pair const& p) {
|
||||
th_explain::th_explain(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode_pair const& p, char const* pma) {
|
||||
m_consequent = c;
|
||||
m_eq = p;
|
||||
m_num_literals = n_lits;
|
||||
m_num_eqs = n_eqs;
|
||||
m_literals = reinterpret_cast<literal*>(reinterpret_cast<char*>(this) + sizeof(th_explain));
|
||||
for (unsigned i = 0; i < n_lits; ++i)
|
||||
char * base_ptr = reinterpret_cast<char*>(this) + sizeof(th_explain);
|
||||
m_literals = reinterpret_cast<literal*>(base_ptr);
|
||||
unsigned i;
|
||||
for (i = 0; i < n_lits; ++i)
|
||||
m_literals[i] = lits[i];
|
||||
m_eqs = reinterpret_cast<enode_pair*>(reinterpret_cast<char*>(this) + sizeof(th_explain) + sizeof(literal) * n_lits);
|
||||
for (unsigned i = 0; i < n_eqs; ++i)
|
||||
m_eqs[i] = eqs[i];
|
||||
|
||||
base_ptr += sizeof(literal) * n_lits;
|
||||
m_eqs = reinterpret_cast<enode_pair*>(base_ptr);
|
||||
for (i = 0; i < n_eqs; ++i)
|
||||
m_eqs[i] = eqs[i];
|
||||
base_ptr += sizeof(enode_pair) * n_eqs;
|
||||
m_pragma = reinterpret_cast<char*>(base_ptr);
|
||||
for (i = 0; pma && pma[i]; ++i)
|
||||
m_pragma[i] = pma[i];
|
||||
m_pragma[i] = 0;
|
||||
}
|
||||
|
||||
th_explain* th_explain::mk(th_euf_solver& th, unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode* x, enode* y) {
|
||||
th_explain* th_explain::mk(th_euf_solver& th, unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode* x, enode* y, char const* pma) {
|
||||
region& r = th.ctx.get_region();
|
||||
void* mem = r.allocate(get_obj_size(n_lits, n_eqs));
|
||||
void* mem = r.allocate(get_obj_size(n_lits, n_eqs, pma));
|
||||
sat::constraint_base::initialize(mem, &th);
|
||||
return new (sat::constraint_base::ptr2mem(mem)) th_explain(n_lits, lits, n_eqs, eqs, c, enode_pair(x, y));
|
||||
}
|
||||
|
||||
th_explain* th_explain::propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, sat::literal consequent) {
|
||||
return mk(th, lits.size(), lits.data(), eqs.size(), eqs.data(), consequent, nullptr, nullptr);
|
||||
th_explain* th_explain::propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, sat::literal consequent, char const* pma) {
|
||||
return mk(th, lits.size(), lits.data(), eqs.size(), eqs.data(), consequent, nullptr, nullptr, pma);
|
||||
}
|
||||
|
||||
th_explain* th_explain::propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, euf::enode* x, euf::enode* y) {
|
||||
return mk(th, lits.size(), lits.data(), eqs.size(), eqs.data(), sat::null_literal, x, y);
|
||||
th_explain* th_explain::propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, euf::enode* x, euf::enode* y, char const* pma) {
|
||||
return mk(th, lits.size(), lits.data(), eqs.size(), eqs.data(), sat::null_literal, x, y, pma);
|
||||
}
|
||||
|
||||
th_explain* th_explain::propagate(th_euf_solver& th, sat::literal lit, euf::enode* x, euf::enode* y) {
|
||||
|
@ -293,6 +305,8 @@ namespace euf {
|
|||
out << "--> " << m_consequent;
|
||||
if (m_eq.first != nullptr)
|
||||
out << "--> " << m_eq.first->get_expr_id() << " == " << m_eq.second->get_expr_id();
|
||||
if (m_pragma != nullptr)
|
||||
out << " p " << m_pragma;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,15 +143,16 @@ namespace euf {
|
|||
region& get_region();
|
||||
|
||||
|
||||
sat::status mk_status();
|
||||
sat::status mk_status(char const* ps = nullptr);
|
||||
bool add_unit(sat::literal lit);
|
||||
bool add_units(sat::literal_vector const& lits);
|
||||
bool add_clause(sat::literal lit) { return add_unit(lit); }
|
||||
bool add_clause(sat::literal a, sat::literal b);
|
||||
bool add_clause(sat::literal a, sat::literal b, char const* ps);
|
||||
bool add_clause(sat::literal a, sat::literal b, sat::literal c);
|
||||
bool add_clause(sat::literal a, sat::literal b, sat::literal c, sat::literal d);
|
||||
bool add_clause(sat::literal_vector const& lits) { return add_clause(lits.size(), lits.data()); }
|
||||
bool add_clause(unsigned n, sat::literal* lits);
|
||||
bool add_clause(sat::literal_vector const& lits, char const* ps = nullptr) { return add_clause(lits.size(), lits.data(), ps); }
|
||||
bool add_clause(unsigned n, sat::literal* lits, char const* ps = nullptr);
|
||||
void add_equiv(sat::literal a, sat::literal b);
|
||||
void add_equiv_and(sat::literal a, sat::literal_vector const& bs);
|
||||
|
||||
|
@ -213,15 +214,16 @@ namespace euf {
|
|||
* that retrieve literals on demand.
|
||||
*/
|
||||
class th_explain {
|
||||
sat::literal m_consequent { sat::null_literal }; // literal consequent for propagations
|
||||
enode_pair m_eq { enode_pair() }; // equality consequent for propagations
|
||||
sat::literal m_consequent = sat::null_literal; // literal consequent for propagations
|
||||
enode_pair m_eq = enode_pair(); // equality consequent for propagations
|
||||
unsigned m_num_literals;
|
||||
unsigned m_num_eqs;
|
||||
sat::literal* m_literals;
|
||||
enode_pair* m_eqs;
|
||||
static size_t get_obj_size(unsigned num_lits, unsigned num_eqs);
|
||||
th_explain(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode_pair const& eq);
|
||||
static th_explain* mk(th_euf_solver& th, unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode* x, enode* y);
|
||||
char* m_pragma;
|
||||
static size_t get_obj_size(unsigned num_lits, unsigned num_eqs, char const* pma);
|
||||
th_explain(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode_pair const& eq, char const* pma = nullptr);
|
||||
static th_explain* mk(th_euf_solver& th, unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs, sat::literal c, enode* x, enode* y, char const* pma = nullptr);
|
||||
|
||||
public:
|
||||
static th_explain* conflict(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs);
|
||||
|
@ -232,8 +234,8 @@ namespace euf {
|
|||
static th_explain* conflict(th_euf_solver& th, sat::literal lit, euf::enode* x, euf::enode* y);
|
||||
static th_explain* conflict(th_euf_solver& th, euf::enode* x, euf::enode* y);
|
||||
static th_explain* propagate(th_euf_solver& th, sat::literal lit, euf::enode* x, euf::enode* y);
|
||||
static th_explain* propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, sat::literal consequent);
|
||||
static th_explain* propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, euf::enode* x, euf::enode* y);
|
||||
static th_explain* propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, sat::literal consequent, char const* pma = nullptr);
|
||||
static th_explain* propagate(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs, euf::enode* x, euf::enode* y, char const* pma = nullptr);
|
||||
|
||||
sat::ext_constraint_idx to_index() const {
|
||||
return sat::constraint_base::mem2base(this);
|
||||
|
@ -268,6 +270,8 @@ namespace euf {
|
|||
|
||||
enode_pair eq_consequent() const { return m_eq; }
|
||||
|
||||
char const* get_pragma() const { return *m_pragma ? m_pragma : nullptr; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue