mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 02:15:19 +00:00
fix for #291. The root issue is that the set of antecedents is recycled as a fixed object between routines. Antecedents that were already allocated for a Gomory cut got reset by the internalizer. This causes unsound bounds axioms to be created
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
d6cb778365
commit
fc592fc856
|
@ -288,11 +288,13 @@ namespace smt {
|
|||
}
|
||||
|
||||
void conflict_resolution::process_antecedent(literal antecedent, unsigned & num_marks) {
|
||||
TRACE("conflict", tout << "processing antecedent: "; m_ctx.display_literal(tout, antecedent); tout << "\n";);
|
||||
bool_var var = antecedent.var();
|
||||
unsigned lvl = m_ctx.get_assign_level(var);
|
||||
SASSERT(var < static_cast<int>(m_ctx.get_num_bool_vars()));
|
||||
|
||||
TRACE("conflict", tout << "processing antecedent (level " << lvl << "):";
|
||||
m_ctx.display_literal(tout, antecedent);
|
||||
m_ctx.display_detailed_literal(tout << " ", antecedent); tout << "\n";);
|
||||
|
||||
if (!m_ctx.is_marked(var) && lvl > m_ctx.get_base_level()) {
|
||||
m_ctx.set_mark(var);
|
||||
m_ctx.inc_bvar_activity(var);
|
||||
|
|
|
@ -172,7 +172,9 @@ namespace smt {
|
|||
}
|
||||
|
||||
void context::assign_core(literal l, b_justification j, bool decision) {
|
||||
TRACE("assign_core", tout << "assigning: " << l << " "; display_literal(tout, l); tout << "\n";);
|
||||
TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " ";
|
||||
display_literal(tout, l); tout << " level: " << m_scope_lvl << "\n";
|
||||
display(tout, j););
|
||||
SASSERT(l.var() < static_cast<int>(m_b_internalized_stack.size()));
|
||||
m_assigned_literals.push_back(l);
|
||||
m_assignment[l.index()] = l_true;
|
||||
|
@ -1609,7 +1611,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
bool context::propagate() {
|
||||
TRACE("propagate", tout << "propagating...\n";);
|
||||
TRACE("propagate", tout << "propagating... " << m_qhead << ":" << m_assigned_literals.size() << "\n";);
|
||||
while (true) {
|
||||
if (inconsistent())
|
||||
return false;
|
||||
|
|
|
@ -1237,6 +1237,8 @@ namespace smt {
|
|||
|
||||
void display_profile(std::ostream & out) const;
|
||||
|
||||
void display(std::ostream& out, b_justification j) const;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Debugging support
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
void context::display_literals_verbose(std::ostream & out, unsigned num_lits, literal const * lits) const {
|
||||
display_verbose(out, m_manager, num_lits, lits, m_bool_var2expr.c_ptr());
|
||||
display_verbose(out, m_manager, num_lits, lits, m_bool_var2expr.c_ptr(), "\n");
|
||||
}
|
||||
|
||||
void context::display_literal_info(std::ostream & out, literal l) const {
|
||||
|
@ -204,9 +204,10 @@ namespace smt {
|
|||
literal_vector::const_iterator end = m_assigned_literals.end();
|
||||
for (; it != end; ++it) {
|
||||
display_literal(out, *it);
|
||||
out << " ";
|
||||
out << ": ";
|
||||
display_verbose(tout, m_manager, 1, &*it, m_bool_var2expr.c_ptr());
|
||||
out << "\n";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -581,15 +582,8 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void context::trace_assign(literal l, b_justification j, bool decision) const {
|
||||
SASSERT(m_manager.has_trace_stream());
|
||||
std::ostream & out = m_manager.trace_stream();
|
||||
out << "[assign] ";
|
||||
display_literal(out, l);
|
||||
if (decision)
|
||||
out << " decision";
|
||||
out << " ";
|
||||
|
||||
void context::display(std::ostream& out, b_justification j) const {
|
||||
switch (j.get_kind()) {
|
||||
case b_justification::AXIOM:
|
||||
out << "axiom";
|
||||
|
@ -597,8 +591,6 @@ namespace smt {
|
|||
case b_justification::BIN_CLAUSE: {
|
||||
literal l2 = j.get_literal();
|
||||
out << "bin-clause ";
|
||||
display_literal(out, l);
|
||||
out << " ";
|
||||
display_literal(out, l2);
|
||||
break;
|
||||
}
|
||||
|
@ -618,5 +610,16 @@ namespace smt {
|
|||
out << "\n";
|
||||
}
|
||||
|
||||
void context::trace_assign(literal l, b_justification j, bool decision) const {
|
||||
SASSERT(m_manager.has_trace_stream());
|
||||
std::ostream & out = m_manager.trace_stream();
|
||||
out << "[assign] ";
|
||||
display_literal(out, l);
|
||||
if (decision)
|
||||
out << " decision";
|
||||
out << " ";
|
||||
display(out, j);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -69,10 +69,10 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
void display_verbose(std::ostream & out, ast_manager& m, unsigned num_lits, literal const * lits, expr * const * bool_var2expr_map) {
|
||||
void display_verbose(std::ostream & out, ast_manager& m, unsigned num_lits, literal const * lits, expr * const * bool_var2expr_map, char const* sep) {
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
if (i > 0)
|
||||
out << " ";
|
||||
out << sep;
|
||||
lits[i].display(out, m, bool_var2expr_map);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace smt {
|
|||
|
||||
void display_compact(std::ostream & out, unsigned num_lits, literal const * lits, expr * const * bool_var2expr_map);
|
||||
|
||||
void display_verbose(std::ostream & out, ast_manager& m, unsigned num_lits, literal const * lits, expr * const * bool_var2expr_map);
|
||||
void display_verbose(std::ostream & out, ast_manager& m, unsigned num_lits, literal const * lits, expr * const * bool_var2expr_map, char const* sep = " ");
|
||||
|
||||
template<typename T>
|
||||
void neg_literals(unsigned num_lits, literal const * lits, T & result) {
|
||||
|
|
|
@ -218,7 +218,7 @@ namespace smt {
|
|||
typedef svector<enode_pair> eq_vector;
|
||||
|
||||
// keep track of coefficients used for bounds for proof generation.
|
||||
class antecedents {
|
||||
class antecedents_t {
|
||||
literal_vector m_lits;
|
||||
eq_vector m_eqs;
|
||||
vector<numeral> m_lit_coeffs;
|
||||
|
@ -233,16 +233,38 @@ namespace smt {
|
|||
void init();
|
||||
|
||||
public:
|
||||
antecedents(): m_init(false) {}
|
||||
antecedents_t(): m_init(false) {}
|
||||
void reset();
|
||||
literal_vector& lits() { return m_lits; }
|
||||
eq_vector& eqs() { return m_eqs; }
|
||||
literal_vector const& lits() const { return m_lits; }
|
||||
eq_vector const& eqs() const { return m_eqs; }
|
||||
void push_lit(literal l, numeral const& r, bool proofs_enabled);
|
||||
void push_eq(enode_pair const& p, numeral const& r, bool proofs_enabled);
|
||||
void append(unsigned sz, literal const* ls) { m_lits.append(sz, ls); }
|
||||
void append(unsigned sz, enode_pair const* ps) { m_eqs.append(sz, ps); }
|
||||
unsigned num_params() const { return empty()?0:m_eq_coeffs.size() + m_lit_coeffs.size() + 1; }
|
||||
numeral const* lit_coeffs() const { return m_lit_coeffs.c_ptr(); }
|
||||
numeral const* eq_coeffs() const { return m_eq_coeffs.c_ptr(); }
|
||||
parameter* params(char const* name);
|
||||
std::ostream& display(theory_arith& th, std::ostream& out) const;
|
||||
};
|
||||
|
||||
class antecedents {
|
||||
theory_arith& th;
|
||||
antecedents_t& a;
|
||||
public:
|
||||
antecedents(theory_arith& th);
|
||||
~antecedents();
|
||||
literal_vector const& lits() const { return a.lits(); }
|
||||
eq_vector const& eqs() const { return a.eqs(); }
|
||||
void push_lit(literal l, numeral const& r, bool e) { a.push_lit(l, r, e); }
|
||||
void push_eq(enode_pair const& p, numeral const& r, bool e) { a.push_eq(p, r, e); }
|
||||
void append(unsigned sz, literal const* ls) { a.append(sz, ls); }
|
||||
void append(unsigned sz, enode_pair const* ps) { a.append(sz, ps); }
|
||||
unsigned num_params() const { return a.num_params(); }
|
||||
numeral const* lit_coeffs() const { return a.lit_coeffs(); }
|
||||
numeral const* eq_coeffs() const { return a.eq_coeffs(); }
|
||||
parameter* params(char const* name) { return a.params(name); }
|
||||
std::ostream& display(std::ostream& out) const { return a.display(th, out); }
|
||||
};
|
||||
|
||||
class gomory_cut_justification;
|
||||
|
@ -324,11 +346,14 @@ namespace smt {
|
|||
public:
|
||||
derived_bound(theory_var v, inf_numeral const & val, bound_kind k):bound(v, val, k, false) {}
|
||||
virtual ~derived_bound() {}
|
||||
literal_vector const& lits() const { return m_lits; }
|
||||
eq_vector const& eqs() const { return m_eqs; }
|
||||
virtual bool has_justification() const { return true; }
|
||||
virtual void push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled);
|
||||
virtual void push_lit(literal l, numeral const&) { m_lits.push_back(l); }
|
||||
virtual void push_eq(enode_pair const& p, numeral const&) { m_eqs.push_back(p); }
|
||||
virtual void display(theory_arith const& th, std::ostream& out) const;
|
||||
|
||||
};
|
||||
|
||||
class justified_derived_bound : public derived_bound {
|
||||
|
@ -460,8 +485,8 @@ namespace smt {
|
|||
|
||||
svector<scope> m_scopes;
|
||||
literal_vector m_tmp_literal_vector2;
|
||||
antecedents m_tmp_antecedents;
|
||||
antecedents m_tmp_antecedents2;
|
||||
antecedents_t m_antecedents[3];
|
||||
unsigned m_antecedents_index;
|
||||
|
||||
struct var_value_hash;
|
||||
friend struct var_value_hash;
|
||||
|
@ -506,6 +531,8 @@ namespace smt {
|
|||
bool relax_bounds() const { return m_params.m_arith_stronger_lemmas; }
|
||||
bool skip_big_coeffs() const { return m_params.m_arith_skip_rows_with_big_coeffs; }
|
||||
bool dump_lemmas() const { return m_params.m_arith_dump_lemmas; }
|
||||
void dump_lemmas(literal l, antecedents const& ante);
|
||||
void dump_lemmas(literal l, derived_bound const& ante);
|
||||
bool process_atoms() const;
|
||||
unsigned get_num_conflicts() const { return m_num_conflicts; }
|
||||
var_kind get_var_kind(theory_var v) const { return m_data[v].kind(); }
|
||||
|
@ -750,7 +777,7 @@ namespace smt {
|
|||
void explain_bound(row const & r, int idx, bool lower, inf_numeral & delta,
|
||||
antecedents & antecedents);
|
||||
void mk_implied_bound(row const & r, unsigned idx, bool lower, theory_var v, bound_kind kind, inf_numeral const & k);
|
||||
void assign_bound_literal(literal l, row const & r, unsigned idx, bool lower, inf_numeral & delta, antecedents& antecedents);
|
||||
void assign_bound_literal(literal l, row const & r, unsigned idx, bool lower, inf_numeral & delta);
|
||||
void propagate_bounds();
|
||||
|
||||
// -----------------------------------
|
||||
|
@ -836,7 +863,9 @@ namespace smt {
|
|||
// Justification
|
||||
//
|
||||
// -----------------------------------
|
||||
void set_conflict(unsigned num_literals, literal const * lits, unsigned num_eqs, enode_pair const * eqs, antecedents& antecedents, bool is_lia, char const* proof_rule);
|
||||
void set_conflict(unsigned num_literals, literal const * lits, unsigned num_eqs, enode_pair const * eqs, antecedents& antecedents, char const* proof_rule);
|
||||
void set_conflict(antecedents const& ante, antecedents& bounds, char const* proof_rule);
|
||||
void set_conflict(derived_bound const& ante, antecedents& bounds, char const* proof_rule);
|
||||
void collect_fixed_var_justifications(row const & r, antecedents& antecedents) const;
|
||||
|
||||
// -----------------------------------
|
||||
|
@ -989,7 +1018,7 @@ namespace smt {
|
|||
gb_result compute_grobner(svector<theory_var> const & nl_cluster);
|
||||
bool max_min_nl_vars();
|
||||
final_check_status process_non_linear();
|
||||
antecedents& get_antecedents();
|
||||
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
|
|
|
@ -316,7 +316,7 @@ namespace smt {
|
|||
// -----------------------------------
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::antecedents::init() {
|
||||
void theory_arith<Ext>::antecedents_t::init() {
|
||||
if (!m_init && !empty()) {
|
||||
m_params.push_back(parameter(symbol("unknown-arith")));
|
||||
for (unsigned i = 0; i < m_lits.size(); i++) {
|
||||
|
@ -330,7 +330,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::antecedents::reset() {
|
||||
void theory_arith<Ext>::antecedents_t::reset() {
|
||||
m_init = false;
|
||||
m_eq_coeffs.reset();
|
||||
m_lit_coeffs.reset();
|
||||
|
@ -340,7 +340,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::antecedents::push_lit(literal l, numeral const& r, bool proofs_enabled) {
|
||||
void theory_arith<Ext>::antecedents_t::push_lit(literal l, numeral const& r, bool proofs_enabled) {
|
||||
m_lits.push_back(l);
|
||||
if (proofs_enabled) {
|
||||
m_lit_coeffs.push_back(r);
|
||||
|
@ -348,7 +348,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::antecedents::push_eq(enode_pair const& p, numeral const& r, bool proofs_enabled) {
|
||||
void theory_arith<Ext>::antecedents_t::push_eq(enode_pair const& p, numeral const& r, bool proofs_enabled) {
|
||||
m_eqs.push_back(p);
|
||||
if (proofs_enabled) {
|
||||
m_eq_coeffs.push_back(r);
|
||||
|
@ -356,7 +356,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
parameter * theory_arith<Ext>::antecedents::params(char const* name) {
|
||||
parameter * theory_arith<Ext>::antecedents_t::params(char const* name) {
|
||||
if (empty()) return 0;
|
||||
init();
|
||||
m_params[0] = parameter(symbol(name));
|
||||
|
@ -740,8 +740,8 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
else {
|
||||
a.lits().append(m_lits.size(), m_lits.c_ptr());
|
||||
a.eqs().append(m_eqs.size(), m_eqs.c_ptr());
|
||||
a.append(m_lits.size(), m_lits.c_ptr());
|
||||
a.append(m_eqs.size(), m_eqs.c_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,8 +804,7 @@ namespace smt {
|
|||
*/
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::accumulate_justification(bound & b, derived_bound& new_bound, numeral const& coeff, literal_idx_set & lits, eq_set & eqs) {
|
||||
antecedents& ante = m_tmp_antecedents;
|
||||
ante.reset();
|
||||
antecedents ante(*this);
|
||||
b.push_justification(ante, coeff, proofs_enabled());
|
||||
unsigned num_lits = ante.lits().size();
|
||||
for (unsigned i = 0; i < num_lits; ++i) {
|
||||
|
|
|
@ -349,7 +349,6 @@ namespace smt {
|
|||
template<typename Ext>
|
||||
void theory_arith<Ext>::mk_axiom(expr * ante, expr * conseq) {
|
||||
ast_manager & m = get_manager();
|
||||
TRACE("arith_axiom", tout << mk_pp(ante, m) << "\n" << mk_pp(conseq, m) << "\n";);
|
||||
context & ctx = get_context();
|
||||
simplifier & s = ctx.get_simplifier();
|
||||
expr_ref s_ante(m), s_conseq(m);
|
||||
|
@ -371,6 +370,9 @@ namespace smt {
|
|||
literal l_conseq = ctx.get_literal(s_conseq);
|
||||
if (negated) l_conseq.neg();
|
||||
|
||||
TRACE("arith_axiom", tout << mk_pp(ante, m) << "\n" << mk_pp(conseq, m) << "\n";
|
||||
tout << s_ante << "\n" << s_conseq << "\n";);
|
||||
|
||||
literal lits[2] = {l_ante, l_conseq};
|
||||
ctx.mk_th_axiom(get_id(), 2, lits);
|
||||
if (ctx.relevancy()) {
|
||||
|
@ -394,12 +396,12 @@ namespace smt {
|
|||
void theory_arith<Ext>::mk_div_axiom(expr * p, expr * q) {
|
||||
if (!m_util.is_zero(q)) {
|
||||
ast_manager & m = get_manager();
|
||||
expr_ref div(m), zero(m), eqz(m), eq(m);
|
||||
TRACE("div_axiom_bug", tout << "expanding div_axiom for: " << mk_pp(p, m) << " / " << mk_pp(q, m) << "\n";);
|
||||
expr * div = m_util.mk_div(p, q);
|
||||
expr * zero = m_util.mk_numeral(rational(0), false);
|
||||
expr_ref eqz(m), eq(m);
|
||||
eqz = m.mk_eq(q, zero);
|
||||
eq = m.mk_eq(m_util.mk_mul(q, div), p);
|
||||
div = m_util.mk_div(p, q);
|
||||
zero = m_util.mk_numeral(rational(0), false);
|
||||
eqz = m.mk_eq(q, zero);
|
||||
eq = m.mk_eq(m_util.mk_mul(q, div), p);
|
||||
TRACE("div_axiom_bug", tout << "eqz: " << mk_pp(eqz, m) << "\neq: " << mk_pp(eq, m) << "\n";);
|
||||
mk_axiom(eqz, eq);
|
||||
}
|
||||
|
@ -410,15 +412,21 @@ namespace smt {
|
|||
if (!m_util.is_zero(divisor)) {
|
||||
// if divisor is zero, then idiv and mod are uninterpreted functions.
|
||||
ast_manager & m = get_manager();
|
||||
expr * div = m_util.mk_idiv(dividend, divisor);
|
||||
expr * mod = m_util.mk_mod(dividend, divisor);
|
||||
expr * zero = m_util.mk_numeral(rational(0), true);
|
||||
expr * abs_divisor = m.mk_ite(m_util.mk_lt(divisor, zero), m_util.mk_sub(zero, divisor), divisor);
|
||||
expr_ref div(m), mod(m), zero(m), abs_divisor(m);
|
||||
expr_ref eqz(m), eq(m), lower(m), upper(m);
|
||||
eqz = m.mk_eq(divisor, zero);
|
||||
eq = m.mk_eq(m_util.mk_add(m_util.mk_mul(divisor, div), mod), dividend);
|
||||
lower = m_util.mk_le(zero, mod);
|
||||
upper = m_util.mk_lt(mod, abs_divisor);
|
||||
div = m_util.mk_idiv(dividend, divisor);
|
||||
mod = m_util.mk_mod(dividend, divisor);
|
||||
zero = m_util.mk_numeral(rational(0), true);
|
||||
abs_divisor = m.mk_ite(m_util.mk_lt(divisor, zero), m_util.mk_sub(zero, divisor), divisor);
|
||||
eqz = m.mk_eq(divisor, zero);
|
||||
eq = m.mk_eq(m_util.mk_add(m_util.mk_mul(divisor, div), mod), dividend);
|
||||
lower = m_util.mk_le(zero, mod);
|
||||
upper = m_util.mk_lt(mod, abs_divisor);
|
||||
TRACE("div_axiom_bug",
|
||||
tout << "eqz: " << mk_pp(eqz, m) << "\neq: " << mk_pp(eq, m) << "\n";
|
||||
tout << "lower: " << mk_pp(lower, m) << "\n";
|
||||
tout << "upper: " << mk_pp(upper, m) << "\n";);
|
||||
|
||||
mk_axiom(eqz, eq);
|
||||
mk_axiom(eqz, lower);
|
||||
mk_axiom(eqz, upper);
|
||||
|
@ -814,6 +822,7 @@ namespace smt {
|
|||
void theory_arith<Ext>::mk_bound_axioms(atom * a1) {
|
||||
theory_var v = a1->get_var();
|
||||
atoms & occs = m_var_occs[v];
|
||||
//SASSERT(v != 15);
|
||||
TRACE("mk_bound_axioms", tout << "add bound axioms for v" << v << " " << a1 << "\n";);
|
||||
if (!get_context().is_searching()) {
|
||||
//
|
||||
|
@ -937,6 +946,8 @@ namespace smt {
|
|||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::flush_bound_axioms() {
|
||||
CTRACE("arith", !m_new_atoms.empty(), tout << "flush bound axioms\n";);
|
||||
|
||||
while (!m_new_atoms.empty()) {
|
||||
ptr_vector<atom> atoms;
|
||||
atoms.push_back(m_new_atoms.back());
|
||||
|
@ -950,6 +961,10 @@ namespace smt {
|
|||
--i;
|
||||
}
|
||||
}
|
||||
TRACE("arith",
|
||||
for (unsigned i = 0; i < atoms.size(); ++i) {
|
||||
atoms[i]->display(*this, tout);
|
||||
});
|
||||
ptr_vector<atom> occs(m_var_occs[v]);
|
||||
|
||||
std::sort(atoms.begin(), atoms.end(), compare_atoms());
|
||||
|
@ -1140,7 +1155,7 @@ namespace smt {
|
|||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::assign_eh(bool_var v, bool is_true) {
|
||||
TRACE("arith", tout << "v" << v << " " << is_true << "\n";);
|
||||
TRACE("arith", tout << "p" << v << " := " << (is_true?"true":"false") << "\n";);
|
||||
atom * a = get_bv2a(v);
|
||||
if (!a) return;
|
||||
SASSERT(get_context().get_assignment(a->get_bool_var()) != l_undef);
|
||||
|
@ -1299,28 +1314,6 @@ namespace smt {
|
|||
final_check_status theory_arith<Ext>::final_check_eh() {
|
||||
TRACE("arith_eq_adapter_info", m_arith_eq_adapter.display_already_processed(tout););
|
||||
TRACE("arith_final_check", display(tout););
|
||||
#if 0
|
||||
if (true /*m_params.m_smtlib_dump_lemmas*/) {
|
||||
literal_buffer tmp;
|
||||
|
||||
for (unsigned i = 0; i < m_asserted_qhead; i++) {
|
||||
bound * b = m_asserted_bounds[i];
|
||||
if (b->is_atom()) {
|
||||
atom* a = static_cast<atom*>(b);
|
||||
bool_var bv = a->get_bool_var();
|
||||
lbool is_true = get_context().get_assignment(bv);
|
||||
if (is_true == l_true) {
|
||||
tmp.push_back(literal(bv));
|
||||
}
|
||||
else if (is_true == l_false) {
|
||||
tmp.push_back(~literal(bv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_context().display_lemma_as_smt_problem(tmp.size(), tmp.c_ptr(), false_literal, "QF_LIA");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!propagate_core())
|
||||
return FC_CONTINUE;
|
||||
|
@ -1530,6 +1523,7 @@ namespace smt {
|
|||
m_branch_cut_counter(0),
|
||||
m_eager_gcd(m_params.m_arith_eager_gcd),
|
||||
m_final_check_idx(0),
|
||||
m_antecedents_index(0),
|
||||
m_var_value_table(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)),
|
||||
m_liberal_final_check(true),
|
||||
m_changed_assignment(false),
|
||||
|
@ -2202,15 +2196,15 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("sign_row_conflict", tout << "v" << x_i << " is_below: " << is_below << " delta: " << delta << "\n"; display_var(tout, x_i);
|
||||
tout << "is_below_lower: " << below_lower(x_i) << ", is_above_upper: " << above_upper(x_i) << "\n";);
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
explain_bound(r, idx, !is_below, delta, ante);
|
||||
b->push_justification(ante, numeral(1), coeffs_enabled());
|
||||
|
||||
TRACE("sign_row_conflict", tout << "v" << x_i << " is_below: " << is_below << " delta: " << delta << "\n"; display_var(tout, x_i);
|
||||
tout << "is_below_lower: " << below_lower(x_i) << ", is_above_upper: " << above_upper(x_i) << "\n";
|
||||
ante.display(tout););
|
||||
|
||||
set_conflict(ante.lits().size(), ante.lits().c_ptr(),
|
||||
ante.eqs().size(), ante.eqs().c_ptr(), ante, is_int(x_i), "farkas");
|
||||
set_conflict(ante, ante, "farkas");
|
||||
// display_bounds_in_smtlib();
|
||||
}
|
||||
|
||||
|
@ -2348,11 +2342,11 @@ namespace smt {
|
|||
template<typename Ext>
|
||||
void theory_arith<Ext>::sign_bound_conflict(bound * b1, bound * b2) {
|
||||
SASSERT(b1->get_var() == b2->get_var());
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
b1->push_justification(ante, numeral(1), coeffs_enabled());
|
||||
b2->push_justification(ante, numeral(1), coeffs_enabled());
|
||||
|
||||
set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), ante, is_int(b1->get_var()), "farkas");
|
||||
set_conflict(ante, ante, "farkas");
|
||||
TRACE("arith_conflict", tout << "bound conflict v" << b1->get_var() << "\n";
|
||||
tout << "bounds: " << b1 << " " << b2 << "\n";);
|
||||
}
|
||||
|
@ -2590,7 +2584,6 @@ namespace smt {
|
|||
if (!relax_bounds() && (!ante.lits().empty() || !ante.eqs().empty()))
|
||||
return;
|
||||
context & ctx = get_context();
|
||||
ante.reset(); // !!!!TBD: should equality ante also be reset here!!!!
|
||||
row_entry const & entry = r[idx];
|
||||
numeral coeff = entry.m_coeff;
|
||||
if (relax_bounds()) {
|
||||
|
@ -2695,7 +2688,6 @@ namespace smt {
|
|||
template<typename Ext>
|
||||
void theory_arith<Ext>::mk_implied_bound(row const & r, unsigned idx, bool is_lower, theory_var v, bound_kind kind, inf_numeral const & k) {
|
||||
atoms const & as = m_var_occs[v];
|
||||
antecedents& ante = get_antecedents();
|
||||
inf_numeral const & epsilon = get_epsilon(v);
|
||||
inf_numeral delta;
|
||||
typename atoms::const_iterator it = as.begin();
|
||||
|
@ -2716,7 +2708,7 @@ namespace smt {
|
|||
}
|
||||
TRACE("propagate_bounds", tout << "v" << v << " >= " << k << ", v" << v << " >= " << k2 << ", delta: " << delta << "\n";
|
||||
display_row(tout, r););
|
||||
assign_bound_literal(l, r, idx, is_lower, delta, ante);
|
||||
assign_bound_literal(l, r, idx, is_lower, delta);
|
||||
}
|
||||
// v <= k k < k2 |- v < k2 |- not v >= k2
|
||||
if (kind == B_UPPER && k < k2) {
|
||||
|
@ -2732,7 +2724,7 @@ namespace smt {
|
|||
if (delta.is_nonneg()) {
|
||||
TRACE("propagate_bounds", tout << "v" << v << " <= " << k << ", not v" << v << " >= " << k2 << ", delta: " << delta << "\n";
|
||||
display_row(tout, r););
|
||||
assign_bound_literal(~l, r, idx, is_lower, delta, ante);
|
||||
assign_bound_literal(~l, r, idx, is_lower, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2747,7 +2739,7 @@ namespace smt {
|
|||
if (delta.is_nonneg()) {
|
||||
TRACE("propagate_bounds", tout << "v" << v << " >= " << k << ", not v" << v << " <= " << k2 << ", delta: " << delta << "\n";
|
||||
display_row(tout, r););
|
||||
assign_bound_literal(~l, r, idx, is_lower, delta, ante);
|
||||
assign_bound_literal(~l, r, idx, is_lower, delta);
|
||||
}
|
||||
}
|
||||
// v <= k k <= k2 |- v <= k2
|
||||
|
@ -2758,7 +2750,7 @@ namespace smt {
|
|||
}
|
||||
TRACE("propagate_bounds", tout << "v" << v << " <= " << k << ", v" << v << " <= " << k2 << ", delta: " << delta << "\n";
|
||||
display_row(tout, r););
|
||||
assign_bound_literal(l, r, idx, is_lower, delta, ante);
|
||||
assign_bound_literal(l, r, idx, is_lower, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2766,28 +2758,34 @@ namespace smt {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::assign_bound_literal(literal l, row const & r, unsigned idx, bool is_lower, inf_numeral & delta, antecedents& ante) {
|
||||
void theory_arith<Ext>::dump_lemmas(literal l, antecedents const& ante) {
|
||||
context & ctx = get_context();
|
||||
if (dump_lemmas()) {
|
||||
TRACE("arith", ante.display(tout) << " --> "; ctx.display_detailed_literal(tout, l); tout << "\n";);
|
||||
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().c_ptr(),
|
||||
ante.eqs().size(), ante.eqs().c_ptr(), l, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::dump_lemmas(literal l, derived_bound const& ante) {
|
||||
context & ctx = get_context();
|
||||
if (dump_lemmas()) {
|
||||
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().c_ptr(),
|
||||
ante.eqs().size(), ante.eqs().c_ptr(), l, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::assign_bound_literal(literal l, row const & r, unsigned idx, bool is_lower, inf_numeral & delta) {
|
||||
m_stats.m_bound_props++;
|
||||
context & ctx = get_context();
|
||||
antecedents ante(*this);
|
||||
explain_bound(r, idx, is_lower, delta, ante);
|
||||
if (dump_lemmas()) {
|
||||
char const * logic = is_int(r.get_base_var()) ? "QF_LIA" : "QF_LRA";
|
||||
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().c_ptr(),
|
||||
ante.eqs().size(), ante.eqs().c_ptr(), l, logic);
|
||||
}
|
||||
dump_lemmas(l, ante);
|
||||
|
||||
TRACE("propagate_bounds",
|
||||
literal_vector::const_iterator it = ante.lits().begin();
|
||||
literal_vector::const_iterator end = ante.lits().end();
|
||||
for (; it != end; ++it) {
|
||||
ctx.display_detailed_literal(tout, *it);
|
||||
tout << " ";
|
||||
}
|
||||
eq_vector::const_iterator it2 = ante.eqs().begin();
|
||||
eq_vector::const_iterator end2 = ante.eqs().end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
tout << "#" << it2->first->get_owner_id() << "=#" << it2->second->get_owner_id() << " ";
|
||||
}
|
||||
tout << " --> ";
|
||||
ante.display(tout) << " --> ";
|
||||
ctx.display_detailed_literal(tout, l);
|
||||
tout << "\n";);
|
||||
if (ante.lits().size() < small_lemma_size() && ante.eqs().empty()) {
|
||||
|
@ -2869,19 +2867,26 @@ namespace smt {
|
|||
// Justification
|
||||
//
|
||||
// -----------------------------------
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::set_conflict(antecedents const& ante, antecedents& bounds, char const* proof_rule) {
|
||||
dump_lemmas(false_literal, ante);
|
||||
set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), bounds, proof_rule);
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::set_conflict(derived_bound const& ante, antecedents& bounds, char const* proof_rule) {
|
||||
dump_lemmas(false_literal, ante);
|
||||
set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), bounds, proof_rule);
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::set_conflict(unsigned num_literals, literal const * lits, unsigned num_eqs, enode_pair const * eqs,
|
||||
antecedents& bounds, bool is_lia, char const* proof_rule) {
|
||||
void theory_arith<Ext>::set_conflict(unsigned num_literals, literal const * lits, unsigned num_eqs, enode_pair const * eqs,
|
||||
antecedents& bounds, char const* proof_rule) {
|
||||
SASSERT(num_literals != 0 || num_eqs != 0);
|
||||
context & ctx = get_context();
|
||||
m_stats.m_conflicts++;
|
||||
m_num_conflicts++;
|
||||
if (dump_lemmas()) {
|
||||
char const * logic = is_lia ? "QF_LIA" : "QF_LRA";
|
||||
ctx.display_lemma_as_smt_problem(num_literals, lits, num_eqs, eqs, false_literal, logic);
|
||||
}
|
||||
region & r = ctx.get_region();
|
||||
TRACE("arith_conflict",
|
||||
for (unsigned i = 0; i < num_literals; i++) {
|
||||
ctx.display_detailed_literal(tout, lits[i]);
|
||||
|
@ -2903,7 +2908,7 @@ namespace smt {
|
|||
record_conflict(num_literals, lits, num_eqs, eqs, bounds.num_params(), bounds.params(proof_rule));
|
||||
ctx.set_conflict(
|
||||
ctx.mk_justification(
|
||||
ext_theory_conflict_justification(get_id(), r, num_literals, lits, num_eqs, eqs,
|
||||
ext_theory_conflict_justification(get_id(), ctx.get_region(), num_literals, lits, num_eqs, eqs,
|
||||
bounds.num_params(), bounds.params(proof_rule))));
|
||||
}
|
||||
|
||||
|
@ -3315,11 +3320,20 @@ namespace smt {
|
|||
*/
|
||||
|
||||
template<typename Ext>
|
||||
typename theory_arith<Ext>::antecedents& theory_arith<Ext>::get_antecedents() {
|
||||
m_tmp_antecedents.reset();
|
||||
return m_tmp_antecedents;
|
||||
theory_arith<Ext>::antecedents::antecedents(theory_arith& th):
|
||||
th(th),
|
||||
a(th.m_antecedents[th.m_antecedents_index]) {
|
||||
SASSERT(th.m_antecedents_index < 3);
|
||||
a.reset();
|
||||
++th.m_antecedents_index;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
theory_arith<Ext>::antecedents::~antecedents() {
|
||||
--th.m_antecedents_index;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* THEORY_ARITH_CORE_H_ */
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace smt {
|
|||
// contain invalid (key -> value) pairs. So, we must check whether v2 is really equal to val (previous test) AND it has
|
||||
// the same sort of v. The following test was missing in a previous version of Z3.
|
||||
if (!is_equal(v, v2) && is_int(v) == is_int(v2)) {
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
|
||||
//
|
||||
// v <= k <= v2 => v <= v2
|
||||
|
@ -241,7 +241,7 @@ namespace smt {
|
|||
is_int(x) == is_int(x2) &&
|
||||
!is_equal(x, x2)) {
|
||||
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
collect_fixed_var_justifications(r, ante);
|
||||
|
||||
//
|
||||
|
@ -256,7 +256,7 @@ namespace smt {
|
|||
|
||||
if (k.is_zero() && y != null_theory_var && !is_equal(x, y) && is_int(x) == is_int(y)) {
|
||||
// found equality x = y
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
collect_fixed_var_justifications(r, ante);
|
||||
TRACE("propagate_cheap_eq", tout << "propagate eq using x-y=0 row:\n"; display_row_info(tout, r););
|
||||
m_stats.m_offset_eqs++;
|
||||
|
@ -296,7 +296,7 @@ namespace smt {
|
|||
if (new_eq) {
|
||||
if (!is_equal(x, x2) && is_int(x) == is_int(x2)) {
|
||||
SASSERT(y == y2 && k == k2);
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
collect_fixed_var_justifications(r, ante);
|
||||
collect_fixed_var_justifications(r2, ante);
|
||||
TRACE("propagate_cheap_eq", tout << "propagate eq two rows:\n";
|
||||
|
|
|
@ -201,12 +201,13 @@ namespace smt {
|
|||
SASSERT(is_int(v));
|
||||
SASSERT(!get_value(v).is_int());
|
||||
m_stats.m_branches++;
|
||||
TRACE("arith_branching", tout << "branching v" << v << " = " << get_value(v) << "\n";
|
||||
TRACE("arith_int", tout << "branching v" << v << " = " << get_value(v) << "\n";
|
||||
display_var(tout, v););
|
||||
numeral k = ceil(get_value(v));
|
||||
rational _k = k.to_rational();
|
||||
expr * bound = m_util.mk_ge(get_enode(v)->get_owner(), m_util.mk_numeral(_k, true));
|
||||
TRACE("arith_branching", tout << mk_bounded_pp(bound, get_manager()) << "\n";);
|
||||
expr_ref bound(get_manager());
|
||||
bound = m_util.mk_ge(get_enode(v)->get_owner(), m_util.mk_numeral(_k, true));
|
||||
TRACE("arith_int", tout << mk_bounded_pp(bound, get_manager()) << "\n";);
|
||||
context & ctx = get_context();
|
||||
ctx.internalize(bound, true);
|
||||
ctx.mark_as_relevant(bound);
|
||||
|
@ -452,11 +453,11 @@ namespace smt {
|
|||
expr_ref pol(m);
|
||||
pol = m_util.mk_add(_args.size(), _args.c_ptr());
|
||||
result = m_util.mk_ge(pol, m_util.mk_numeral(k, all_int));
|
||||
TRACE("arith_mk_polynomial", tout << "before simplification:\n" << mk_pp(pol, m) << "\n";);
|
||||
TRACE("arith_mk_polynomial", tout << "before simplification:\n" << result << "\n";);
|
||||
simplifier & s = get_context().get_simplifier();
|
||||
proof_ref pr(m);
|
||||
s(result, result, pr);
|
||||
TRACE("arith_mk_polynomial", tout << "after simplification:\n" << mk_pp(pol, m) << "\n";);
|
||||
TRACE("arith_mk_polynomial", tout << "after simplification:\n" << result << "\n";);
|
||||
SASSERT(is_well_sorted(get_manager(), result));
|
||||
}
|
||||
|
||||
|
@ -498,7 +499,7 @@ namespace smt {
|
|||
|
||||
TRACE("gomory_cut", tout << "applying cut at:\n"; display_row_info(tout, r););
|
||||
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
|
||||
m_stats.m_gomory_cuts++;
|
||||
|
||||
|
@ -508,6 +509,8 @@ namespace smt {
|
|||
|
||||
numeral f_0 = Ext::fractional_part(m_value[x_i]);
|
||||
numeral one_minus_f_0 = numeral(1) - f_0;
|
||||
SASSERT(!f_0.is_zero());
|
||||
SASSERT(!one_minus_f_0.is_zero());
|
||||
|
||||
numeral lcm_den(1);
|
||||
unsigned num_ints = 0;
|
||||
|
@ -521,36 +524,30 @@ namespace smt {
|
|||
a_ij.neg(); // make the used format compatible with the format used in: Integrating Simplex with DPLL(T)
|
||||
if (is_real(x_j)) {
|
||||
numeral new_a_ij;
|
||||
TRACE("gomory_cut_detail", tout << a_ij << "*v" << x_j << "\n";);
|
||||
if (at_lower(x_j)) {
|
||||
if (a_ij.is_pos()) {
|
||||
new_a_ij = a_ij / one_minus_f_0;
|
||||
}
|
||||
else {
|
||||
TRUSTME(!f_0.is_zero());
|
||||
new_a_ij = a_ij / f_0;
|
||||
new_a_ij.neg();
|
||||
}
|
||||
// k += new_a_ij * lower_bound(x_j).get_rational();
|
||||
k.addmul(new_a_ij, lower_bound(x_j).get_rational());
|
||||
lower(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
|
||||
}
|
||||
else {
|
||||
SASSERT(at_upper(x_j));
|
||||
if (a_ij.is_pos()) {
|
||||
TRUSTME(!f_0.is_zero());
|
||||
new_a_ij = a_ij / f_0;
|
||||
new_a_ij.neg(); // the upper terms are inverted.
|
||||
}
|
||||
else {
|
||||
// new_a_ij = - a_ij / one_minus_f_0
|
||||
// new_a_ij.neg() // the upper terms are inverted
|
||||
new_a_ij = a_ij / one_minus_f_0;
|
||||
new_a_ij = a_ij / one_minus_f_0;
|
||||
}
|
||||
// k += new_a_ij * upper_bound(x_j).get_rational();
|
||||
k.addmul(new_a_ij, upper_bound(x_j).get_rational());
|
||||
upper(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
|
||||
}
|
||||
TRACE("gomory_cut_detail", tout << a_ij << "*v" << x_j << " k: " << k << "\n";);
|
||||
pol.push_back(row_entry(new_a_ij, x_j));
|
||||
}
|
||||
else {
|
||||
|
@ -572,7 +569,6 @@ namespace smt {
|
|||
else {
|
||||
new_a_ij = (numeral(1) - f_j) / f_0;
|
||||
}
|
||||
// k += new_a_ij * lower_bound(x_j).get_rational();
|
||||
k.addmul(new_a_ij, lower_bound(x_j).get_rational());
|
||||
lower(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
|
||||
}
|
||||
|
@ -585,11 +581,10 @@ namespace smt {
|
|||
new_a_ij = (numeral(1) - f_j) / one_minus_f_0;
|
||||
}
|
||||
new_a_ij.neg(); // the upper terms are inverted
|
||||
// k += new_a_ij * upper_bound(x_j).get_rational();
|
||||
k.addmul(new_a_ij, upper_bound(x_j).get_rational());
|
||||
upper(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
|
||||
}
|
||||
TRACE("gomory_cut_detail", tout << "new_a_ij: " << new_a_ij << "\n";);
|
||||
TRACE("gomory_cut_detail", tout << "new_a_ij: " << new_a_ij << " k: " << k << "\n";);
|
||||
pol.push_back(row_entry(new_a_ij, x_j));
|
||||
lcm_den = lcm(lcm_den, denominator(new_a_ij));
|
||||
}
|
||||
|
@ -603,7 +598,7 @@ namespace smt {
|
|||
if (pol.empty()) {
|
||||
SASSERT(k.is_pos());
|
||||
// conflict 0 >= k where k is positive
|
||||
set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), ante, true, "gomory-cut");
|
||||
set_conflict(ante, ante, "gomory-cut");
|
||||
return true;
|
||||
}
|
||||
else if (pol.size() == 1) {
|
||||
|
@ -639,18 +634,19 @@ namespace smt {
|
|||
}
|
||||
TRACE("gomory_cut_detail", tout << "after *lcm\n";
|
||||
for (unsigned i = 0; i < pol.size(); i++) {
|
||||
tout << pol[i].m_coeff << " " << pol[i].m_var << "\n";
|
||||
tout << pol[i].m_coeff << " * v" << pol[i].m_var << "\n";
|
||||
}
|
||||
tout << "k: " << k << "\n";);
|
||||
}
|
||||
mk_polynomial_ge(pol.size(), pol.c_ptr(), k.to_rational(), bound);
|
||||
}
|
||||
TRACE("gomory_cut", tout << "new cut:\n" << mk_pp(bound, get_manager()) << "\n";);
|
||||
TRACE("gomory_cut", tout << "new cut:\n" << bound << "\n"; ante.display(tout););
|
||||
literal l = null_literal;
|
||||
context & ctx = get_context();
|
||||
ctx.internalize(bound, true);
|
||||
l = ctx.get_literal(bound);
|
||||
ctx.mark_as_relevant(l);
|
||||
dump_lemmas(l, ante);
|
||||
ctx.assign(l, ctx.mk_justification(
|
||||
gomory_cut_justification(
|
||||
get_id(), ctx.get_region(),
|
||||
|
@ -721,7 +717,7 @@ namespace smt {
|
|||
|
||||
if (!(consts / gcds).is_int()) {
|
||||
TRACE("gcd_test", tout << "row failed the GCD test:\n"; display_row_info(tout, r););
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
collect_fixed_var_justifications(r, ante);
|
||||
context & ctx = get_context();
|
||||
ctx.set_conflict(
|
||||
|
@ -754,7 +750,7 @@ namespace smt {
|
|||
numeral l(consts);
|
||||
numeral u(consts);
|
||||
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
|
||||
|
||||
typename vector<row_entry>::const_iterator it = r.begin_entries();
|
||||
|
|
|
@ -1910,11 +1910,10 @@ namespace smt {
|
|||
*/
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::set_conflict(v_dependency * d) {
|
||||
bool is_lia = false; // TODO: fix it, but this is only used for debugging.
|
||||
antecedents& ante = get_antecedents();
|
||||
antecedents ante(*this);
|
||||
derived_bound b(null_theory_var, inf_numeral(0), B_LOWER);
|
||||
dependency2new_bound(d, b);
|
||||
set_conflict(b.m_lits.size(), b.m_lits.c_ptr(), b.m_eqs.size(), b.m_eqs.c_ptr(), ante, is_lia, "arith_nl");
|
||||
set_conflict(b, ante, "arith_nl");
|
||||
TRACE("non_linear",
|
||||
for (unsigned i = 0; i < b.m_lits.size(); ++i) {
|
||||
tout << b.m_lits[i] << " ";
|
||||
|
|
|
@ -399,6 +399,18 @@ namespace smt {
|
|||
out << "\n";
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
std::ostream& theory_arith<Ext>::antecedents_t::display(theory_arith& th, std::ostream & out) const {
|
||||
th.get_context().display_literals_verbose(out, lits().size(), lits().c_ptr());
|
||||
if (!lits().empty()) out << "\n";
|
||||
ast_manager& m = th.get_manager();
|
||||
for (unsigned i = 0; i < m_eqs.size(); ++i) {
|
||||
out << mk_pp(m_eqs[i].first->get_owner(), m) << " ";
|
||||
out << mk_pp(m_eqs[i].second->get_owner(), m) << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::display_deps(std::ostream & out, v_dependency* dep) {
|
||||
ptr_vector<void> bounds;
|
||||
|
|
|
@ -204,7 +204,7 @@ struct scoped_timer::imp {
|
|||
throw default_exception("failed to destroy pthread attributes object");
|
||||
#elif defined(_LINUX_) || defined(_FREEBSD_)
|
||||
// Linux & FreeBSD
|
||||
timer_delete(m_timerid);
|
||||
timer_delete(m_timerid);
|
||||
#else
|
||||
// Other Platforms
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue