3
0
Fork 0
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:
Nikolaj Bjorner 2017-01-09 21:23:00 -08:00
parent c69a86e647
commit 8d09b6e4a8
11 changed files with 182 additions and 48 deletions

View file

@ -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; }

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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