mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
add at-least and pbge to API, fix for issue #864
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
c69a86e647
commit
8d09b6e4a8
11 changed files with 182 additions and 48 deletions
|
@ -24,7 +24,9 @@ Revision History:
|
|||
namespace smt {
|
||||
|
||||
struct bool_var_data {
|
||||
private:
|
||||
b_justification m_justification;
|
||||
public:
|
||||
unsigned m_scope_lvl:24; //!< scope level of when the variable was assigned.
|
||||
unsigned m_mark:1;
|
||||
unsigned m_assumption:1;
|
||||
|
@ -45,6 +47,14 @@ namespace smt {
|
|||
public:
|
||||
|
||||
unsigned get_intern_level() const { return m_iscope_lvl; }
|
||||
|
||||
b_justification justification() const { return m_justification; }
|
||||
|
||||
void set_axiom() { m_justification = b_justification::mk_axiom(); }
|
||||
|
||||
void set_null_justification() { m_justification = null_b_justification; }
|
||||
|
||||
void set_justification(b_justification const& j) { m_justification = j; }
|
||||
|
||||
bool is_atom() const { return m_atom; }
|
||||
|
||||
|
|
|
@ -496,13 +496,15 @@ namespace smt {
|
|||
|
||||
unsigned idx = skip_literals_above_conflict_level();
|
||||
|
||||
TRACE("conflict", m_ctx.display_literal_verbose(tout, not_l); m_ctx.display(tout << " ", conflict););
|
||||
|
||||
// save space for first uip
|
||||
m_lemma.push_back(null_literal);
|
||||
m_lemma_atoms.push_back(0);
|
||||
|
||||
unsigned num_marks = 0;
|
||||
if (not_l != null_literal) {
|
||||
TRACE("conflict", tout << "not_l: "; m_ctx.display_literal(tout, not_l); tout << "\n";);
|
||||
TRACE("conflict", tout << "not_l: "; m_ctx.display_literal_verbose(tout, not_l); tout << "\n";);
|
||||
process_antecedent(not_l, num_marks);
|
||||
}
|
||||
|
||||
|
@ -514,7 +516,7 @@ namespace smt {
|
|||
get_manager().trace_stream() << "\n";
|
||||
}
|
||||
|
||||
TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal(tout, consequent); tout << "\n";
|
||||
TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal_verbose(tout, consequent); tout << "\n";
|
||||
tout << "num_marks: " << num_marks << ", js kind: " << js.get_kind() << "\n";);
|
||||
SASSERT(js != null_b_justification);
|
||||
switch (js.get_kind()) {
|
||||
|
@ -1076,6 +1078,7 @@ namespace smt {
|
|||
return true;
|
||||
SASSERT(js.get_kind() != b_justification::BIN_CLAUSE);
|
||||
CTRACE("visit_b_justification_bug", js.get_kind() == b_justification::AXIOM, tout << "l: " << l << "\n"; m_ctx.display(tout););
|
||||
|
||||
if (js.get_kind() == b_justification::AXIOM)
|
||||
return true;
|
||||
SASSERT(js.get_kind() != b_justification::AXIOM);
|
||||
|
@ -1089,14 +1092,17 @@ namespace smt {
|
|||
i = 1;
|
||||
}
|
||||
else {
|
||||
SASSERT(cls->get_literal(1) == l);
|
||||
if (get_proof(~cls->get_literal(0)) == 0)
|
||||
visited = false;
|
||||
i = 2;
|
||||
}
|
||||
}
|
||||
for (; i < num_lits; i++)
|
||||
for (; i < num_lits; i++) {
|
||||
SASSERT(cls->get_literal(i) != l);
|
||||
if (get_proof(~cls->get_literal(i)) == 0)
|
||||
visited = false;
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
else
|
||||
|
@ -1251,14 +1257,19 @@ namespace smt {
|
|||
}
|
||||
tout << "\n";);
|
||||
init_mk_proof();
|
||||
literal consequent = false_literal;
|
||||
if (not_l != null_literal)
|
||||
consequent = ~not_l;
|
||||
visit_b_justification(consequent, conflict);
|
||||
if (not_l != null_literal)
|
||||
literal consequent;
|
||||
if (not_l == null_literal) {
|
||||
consequent = false_literal;
|
||||
}
|
||||
else {
|
||||
consequent = ~not_l;
|
||||
m_todo_pr.push_back(tp_elem(not_l));
|
||||
}
|
||||
visit_b_justification(consequent, conflict);
|
||||
|
||||
while (!m_todo_pr.empty()) {
|
||||
tp_elem & elem = m_todo_pr.back();
|
||||
|
||||
switch (elem.m_kind) {
|
||||
case tp_elem::EQUALITY: {
|
||||
enode * lhs = elem.m_lhs;
|
||||
|
|
|
@ -261,10 +261,11 @@ namespace smt {
|
|||
m_assignment[false_literal.index()] = l_false;
|
||||
if (m_manager.proofs_enabled()) {
|
||||
proof * pr = m_manager.mk_true_proof();
|
||||
m_bdata[true_bool_var].m_justification = b_justification(mk_justification(justification_proof_wrapper(*this, pr)));
|
||||
|
||||
set_justification(true_bool_var, m_bdata[true_bool_var], b_justification(mk_justification(justification_proof_wrapper(*this, pr))));
|
||||
}
|
||||
else {
|
||||
m_bdata[true_bool_var].m_justification = b_justification::mk_axiom();
|
||||
m_bdata[true_bool_var].set_axiom();
|
||||
}
|
||||
m_true_enode = mk_enode(t, true, true, false);
|
||||
// internalizer is marking enodes as interpreted whenever the associated ast is a value and a constant.
|
||||
|
@ -292,6 +293,12 @@ namespace smt {
|
|||
std::swap(lhs, rhs);
|
||||
return m_manager.mk_eq(lhs, rhs);
|
||||
}
|
||||
|
||||
void context::set_justification(bool_var v, bool_var_data& d, b_justification const& j) {
|
||||
SASSERT(validate_justification(v, d, j));
|
||||
d.set_justification(j);
|
||||
}
|
||||
|
||||
|
||||
void context::assign_core(literal l, b_justification j, bool decision) {
|
||||
TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " ";
|
||||
|
@ -302,7 +309,7 @@ namespace smt {
|
|||
m_assignment[l.index()] = l_true;
|
||||
m_assignment[(~l).index()] = l_false;
|
||||
bool_var_data & d = get_bdata(l.var());
|
||||
d.m_justification = j;
|
||||
set_justification(l.var(), d, j);
|
||||
d.m_scope_lvl = m_scope_lvl;
|
||||
if (m_fparams.m_restart_adaptive && d.m_phase_available) {
|
||||
m_agility *= m_fparams.m_agility_factor;
|
||||
|
@ -1406,7 +1413,8 @@ namespace smt {
|
|||
else {
|
||||
TRACE("add_diseq", display_eq_detail(tout, bool_var2enode(v)););
|
||||
if (!add_diseq(get_enode(lhs), get_enode(rhs)) && !inconsistent()) {
|
||||
set_conflict(b_justification(mk_justification(eq_propagation_justification(get_enode(lhs), get_enode(rhs)))), ~l);
|
||||
literal not_eq = literal(l.var(), true);
|
||||
set_conflict(b_justification(mk_justification(eq_propagation_justification(get_enode(lhs), get_enode(rhs)))), not_eq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2042,7 +2050,7 @@ namespace smt {
|
|||
m_assignment[(~l).index()] = l_undef;
|
||||
bool_var v = l.var();
|
||||
bool_var_data & d = get_bdata(v);
|
||||
d.m_justification = null_b_justification;
|
||||
d.set_null_justification();
|
||||
m_case_split_queue->unassign_var_eh(v);
|
||||
}
|
||||
|
||||
|
@ -2593,10 +2601,10 @@ namespace smt {
|
|||
cls->set_justification(0);
|
||||
m_justifications.push_back(js);
|
||||
}
|
||||
m_bdata[v0].m_justification = b_justification(js);
|
||||
set_justification(v0, m_bdata[v0], b_justification(js));
|
||||
}
|
||||
else
|
||||
m_bdata[v0].m_justification = b_justification::mk_axiom();
|
||||
m_bdata[v0].set_axiom();
|
||||
}
|
||||
}
|
||||
del_clause(cls);
|
||||
|
|
|
@ -363,9 +363,11 @@ namespace smt {
|
|||
void get_assignments(expr_ref_vector& assignments);
|
||||
|
||||
b_justification get_justification(bool_var v) const {
|
||||
return get_bdata(v).m_justification;
|
||||
return get_bdata(v).justification();
|
||||
}
|
||||
|
||||
void set_justification(bool_var v, bool_var_data& d, b_justification const& j);
|
||||
|
||||
bool has_th_justification(bool_var v, theory_id th_id) const {
|
||||
b_justification js = get_justification(v);
|
||||
return js.get_kind() == b_justification::JUSTIFICATION && js.get_justification()->get_from_theory() == th_id;
|
||||
|
@ -1381,6 +1383,8 @@ namespace smt {
|
|||
void validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||
expr_ref_vector const& conseq, expr_ref_vector const& unfixed);
|
||||
|
||||
bool validate_justification(bool_var v, bool_var_data const& d, b_justification const& j);
|
||||
|
||||
void justify(literal lit, index_set& s);
|
||||
|
||||
void extract_cores(expr_ref_vector const& asms, vector<expr_ref_vector>& cores, unsigned& min_core_size);
|
||||
|
|
|
@ -402,6 +402,20 @@ namespace smt {
|
|||
|
||||
#endif
|
||||
|
||||
bool context::validate_justification(bool_var v, bool_var_data const& d, b_justification const& j) {
|
||||
if (j.get_kind() == b_justification::CLAUSE && v != true_bool_var) {
|
||||
clause* cls = j.get_clause();
|
||||
unsigned num_lits = cls->get_num_literals();
|
||||
literal l = cls->get_literal(0);
|
||||
if (l.var() != v) {
|
||||
l = cls->get_literal(1);
|
||||
}
|
||||
SASSERT(l.var() == v);
|
||||
SASSERT(m_assignment[l.index()] == l_true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool context::validate_model() {
|
||||
if (!m_proto_model) {
|
||||
return true;
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace smt {
|
|||
out << "true";
|
||||
else if (*this == false_literal)
|
||||
out << "false";
|
||||
else if (*this == null_literal)
|
||||
out << "null";
|
||||
else if (sign())
|
||||
out << "(not " << mk_pp(bool_var2expr_map[var()], m) << ")";
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue