mirror of
https://github.com/Z3Prover/z3
synced 2025-06-23 14:23:40 +00:00
trim
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
f8ca692dee
commit
4e780d0cc8
3 changed files with 116 additions and 75 deletions
|
@ -189,6 +189,8 @@ class proof_trim {
|
||||||
cmd_context& ctx;
|
cmd_context& ctx;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
sat::proof_trim trim;
|
sat::proof_trim trim;
|
||||||
|
vector<expr_ref_vector> m_clauses;
|
||||||
|
bool_vector m_is_infer;
|
||||||
|
|
||||||
void mk_clause(expr_ref_vector const& clause) {
|
void mk_clause(expr_ref_vector const& clause) {
|
||||||
trim.init_clause();
|
trim.init_clause();
|
||||||
|
@ -214,9 +216,11 @@ public:
|
||||||
trim(gparams::get_module("sat"), m.limit()) {
|
trim(gparams::get_module("sat"), m.limit()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void assume(expr_ref_vector const& _clause, bool is_initial = true) {
|
void assume(expr_ref_vector const& clause) {
|
||||||
mk_clause(_clause);
|
mk_clause(clause);
|
||||||
trim.assume(true);
|
trim.assume(m_clauses.size());
|
||||||
|
m_clauses.push_back(clause);
|
||||||
|
m_is_infer.push_back(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void del(expr_ref_vector const& _clause) {
|
void del(expr_ref_vector const& _clause) {
|
||||||
|
@ -224,14 +228,42 @@ public:
|
||||||
trim.del();
|
trim.del();
|
||||||
}
|
}
|
||||||
|
|
||||||
void infer(expr_ref_vector const& _clause, app*) {
|
void infer(expr_ref_vector const& clause, app* hint) {
|
||||||
mk_clause(_clause);
|
mk_clause(clause);
|
||||||
trim.infer();
|
trim.infer(m_clauses.size());
|
||||||
|
m_clauses.push_back(clause);
|
||||||
|
if (hint)
|
||||||
|
m_clauses.back().push_back(hint);
|
||||||
|
m_is_infer.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updt_params(params_ref const& p) {
|
void updt_params(params_ref const& p) {
|
||||||
trim.updt_params(p);
|
trim.updt_params(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void do_trim(std::ostream& out) {
|
||||||
|
ast_pp_util pp(m);
|
||||||
|
auto ids = trim.trim();
|
||||||
|
for (unsigned id : ids) {
|
||||||
|
auto const& clause = m_clauses[id];
|
||||||
|
bool is_infer = m_is_infer[id];
|
||||||
|
for (expr* e : clause)
|
||||||
|
pp.collect(e);
|
||||||
|
pp.display_decls(out);
|
||||||
|
for (expr* e : clause)
|
||||||
|
pp.define_expr(out, e);
|
||||||
|
|
||||||
|
if (!is_infer)
|
||||||
|
out << "(assume ";
|
||||||
|
else
|
||||||
|
out << "(infer";
|
||||||
|
for (expr* e : clause)
|
||||||
|
pp.display_expr_def(out << " ", e);
|
||||||
|
out << ")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class proof_saver {
|
class proof_saver {
|
||||||
|
|
|
@ -29,12 +29,13 @@ namespace sat {
|
||||||
Output: reduced trail - result
|
Output: reduced trail - result
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<literal_vector> proof_trim::trim() {
|
unsigned_vector proof_trim::trim() {
|
||||||
vector<literal_vector> result;
|
unsigned_vector result;
|
||||||
m_core_literals.reset();
|
m_core_literals.reset();
|
||||||
m_core_literals.insert(literal_vector());
|
m_core_literals.insert(literal_vector());
|
||||||
|
m_propagated.resize(num_vars(), false);
|
||||||
for (unsigned i = m_trail.size(); i-- > 0; ) {
|
for (unsigned i = m_trail.size(); i-- > 0; ) {
|
||||||
auto const& [cl, clp, is_add, is_initial] = m_trail[i];
|
auto const& [id, cl, clp, is_add, is_initial] = m_trail[i];
|
||||||
if (!is_add) {
|
if (!is_add) {
|
||||||
revive(cl, clp);
|
revive(cl, clp);
|
||||||
continue;
|
continue;
|
||||||
|
@ -43,7 +44,7 @@ namespace sat {
|
||||||
del(cl, clp);
|
del(cl, clp);
|
||||||
if (!in_core(cl, clp))
|
if (!in_core(cl, clp))
|
||||||
continue;
|
continue;
|
||||||
result.push_back(cl);
|
result.push_back(id);
|
||||||
if (is_initial)
|
if (is_initial)
|
||||||
continue;
|
continue;
|
||||||
conflict_analysis_core(cl, clp);
|
conflict_analysis_core(cl, clp);
|
||||||
|
@ -90,6 +91,12 @@ namespace sat {
|
||||||
for (literal lit : cl)
|
for (literal lit : cl)
|
||||||
m_in_clause.insert(lit.index());
|
m_in_clause.insert(lit.index());
|
||||||
|
|
||||||
|
auto unassign_literal = [&](literal l) {
|
||||||
|
m_in_coi.insert((~l).index());
|
||||||
|
s.m_assignment[l.index()] = l_undef;
|
||||||
|
s.m_assignment[(~l).index()] = l_undef;
|
||||||
|
};
|
||||||
|
|
||||||
bool on_trail = false;
|
bool on_trail = false;
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (unsigned i = 0; i < s.trail_size(); ++i) {
|
for (unsigned i = 0; i < s.trail_size(); ++i) {
|
||||||
|
@ -97,9 +104,7 @@ namespace sat {
|
||||||
if (m_in_clause.contains(l.index())) {
|
if (m_in_clause.contains(l.index())) {
|
||||||
SASSERT(!on_trail);
|
SASSERT(!on_trail);
|
||||||
on_trail = true;
|
on_trail = true;
|
||||||
m_in_coi.insert((~l).index());
|
unassign_literal(l);
|
||||||
s.m_assignment[l.index()] = l_undef;
|
|
||||||
s.m_assignment[(~l).index()] = l_undef;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!on_trail) {
|
if (!on_trail) {
|
||||||
|
@ -119,11 +124,8 @@ namespace sat {
|
||||||
else
|
else
|
||||||
UNREACHABLE(); // approach does not work for external justifications
|
UNREACHABLE(); // approach does not work for external justifications
|
||||||
|
|
||||||
if (in_coi) {
|
if (in_coi)
|
||||||
m_in_coi.insert((~l).index());
|
unassign_literal(l);
|
||||||
s.m_assignment[l.index()] = l_undef;
|
|
||||||
s.m_assignment[(~l).index()] = l_undef;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
s.m_trail[j++] = s.m_trail[i];
|
s.m_trail[j++] = s.m_trail[i];
|
||||||
}
|
}
|
||||||
|
@ -171,20 +173,37 @@ namespace sat {
|
||||||
s.propagate(false);
|
s.propagate(false);
|
||||||
}
|
}
|
||||||
SASSERT(s.inconsistent());
|
SASSERT(s.inconsistent());
|
||||||
|
for (unsigned i = trail_size0; i < s.m_trail.size(); ++i)
|
||||||
|
m_propagated[s.m_trail[i].var()] = true;
|
||||||
|
|
||||||
auto add_dependency = [&](literal lit) {
|
if (s.m_not_l != null_literal)
|
||||||
|
add_dependency(s.m_not_l);
|
||||||
|
add_dependency(s.m_conflict);
|
||||||
|
|
||||||
|
for (unsigned i = s.m_trail.size(); i-- > trail_size0; ) {
|
||||||
|
bool_var v = s.m_trail[i].var();
|
||||||
|
m_propagated[v] = false;
|
||||||
|
if (!s.is_marked(v))
|
||||||
|
continue;
|
||||||
|
s.reset_mark(v);
|
||||||
|
add_dependency(s.get_justification(v));
|
||||||
|
}
|
||||||
|
s.pop(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proof_trim::add_dependency(literal lit) {
|
||||||
bool_var v = lit.var();
|
bool_var v = lit.var();
|
||||||
if (s.lvl(v) == 0) {
|
if (m_propagated[v]) // literal was propagated after assuming ~C
|
||||||
|
s.mark(v);
|
||||||
|
else if (s.lvl(v) == 0) { // literal depends on level 0, it is not assumed by ~C
|
||||||
// inefficient for repeated insertions ?
|
// inefficient for repeated insertions ?
|
||||||
auto j = s.m_justification[v];
|
auto j = s.get_justification(v);
|
||||||
literal lit = literal(v, s.value(v) == l_false);
|
literal lit = literal(v, s.value(v) == l_false);
|
||||||
add_core(lit, j);
|
add_core(lit, j);
|
||||||
}
|
}
|
||||||
else if (s.lvl(v) == 2)
|
}
|
||||||
s.mark(v);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto add_jdependency = [&](justification j) {
|
void proof_trim::add_dependency(justification j) {
|
||||||
switch (j.get_kind()) {
|
switch (j.get_kind()) {
|
||||||
case justification::BINARY:
|
case justification::BINARY:
|
||||||
add_dependency(j.get_literal());
|
add_dependency(j.get_literal());
|
||||||
|
@ -198,25 +217,15 @@ namespace sat {
|
||||||
if (s.value(lit) == l_false)
|
if (s.value(lit) == l_false)
|
||||||
add_dependency(lit);
|
add_dependency(lit);
|
||||||
break;
|
break;
|
||||||
|
case justification::EXT_JUSTIFICATION:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (s.m_not_l != null_literal)
|
|
||||||
add_dependency(s.m_not_l);
|
|
||||||
add_jdependency(s.m_conflict);
|
|
||||||
|
|
||||||
for (unsigned i = s.m_trail.size(); i-- > trail_size0; ) {
|
|
||||||
bool_var v = s.m_trail[i].var();
|
|
||||||
if (!s.is_marked(v))
|
|
||||||
continue;
|
|
||||||
s.reset_mark(v);
|
|
||||||
add_jdependency(s.m_justification[v]);
|
|
||||||
}
|
|
||||||
s.pop(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void proof_trim::add_core(literal l, justification j) {
|
void proof_trim::add_core(literal l, justification j) {
|
||||||
m_clause.reset();
|
m_clause.reset();
|
||||||
switch (j.get_kind()) {
|
switch (j.get_kind()) {
|
||||||
|
@ -256,7 +265,6 @@ namespace sat {
|
||||||
s.mk_clause(cl, status::redundant());
|
s.mk_clause(cl, status::redundant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
clause* proof_trim::del(literal_vector const& cl) {
|
clause* proof_trim::del(literal_vector const& cl) {
|
||||||
clause* cp = nullptr;
|
clause* cp = nullptr;
|
||||||
IF_VERBOSE(3, verbose_stream() << "del: " << cl << "\n");
|
IF_VERBOSE(3, verbose_stream() << "del: " << cl << "\n");
|
||||||
|
@ -285,17 +293,15 @@ namespace sat {
|
||||||
v.push_back(cl);
|
v.push_back(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proof_trim::proof_trim(params_ref const& p, reslimit& lim):
|
proof_trim::proof_trim(params_ref const& p, reslimit& lim):
|
||||||
s(p, lim)
|
s(p, lim)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void proof_trim::assume(bool is_initial) {
|
void proof_trim::assume(unsigned id, bool is_initial) {
|
||||||
std::sort(m_clause.begin(), m_clause.end());
|
std::sort(m_clause.begin(), m_clause.end());
|
||||||
IF_VERBOSE(3, verbose_stream() << "add: " << m_clause << "\n");
|
IF_VERBOSE(3, verbose_stream() << "add: " << m_clause << "\n");
|
||||||
auto* cl = s.mk_clause(m_clause, status::redundant());
|
auto* cl = s.mk_clause(m_clause, status::redundant());
|
||||||
m_trail.push_back({ m_clause, cl, true, is_initial });
|
m_trail.push_back({ id, m_clause, cl, true, is_initial });
|
||||||
s.propagate(false);
|
s.propagate(false);
|
||||||
save(m_clause, cl);
|
save(m_clause, cl);
|
||||||
}
|
}
|
||||||
|
@ -303,11 +309,11 @@ namespace sat {
|
||||||
void proof_trim::del() {
|
void proof_trim::del() {
|
||||||
std::sort(m_clause.begin(), m_clause.end());
|
std::sort(m_clause.begin(), m_clause.end());
|
||||||
clause* cp = del(m_clause);
|
clause* cp = del(m_clause);
|
||||||
m_trail.push_back({ m_clause, cp, false, true });
|
m_trail.push_back({ 0, m_clause, cp, false, true });
|
||||||
}
|
}
|
||||||
|
|
||||||
void proof_trim::infer() {
|
void proof_trim::infer(unsigned id) {
|
||||||
assume(false);
|
assume(id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace sat {
|
||||||
literal_vector m_clause;
|
literal_vector m_clause;
|
||||||
uint_set m_in_clause;
|
uint_set m_in_clause;
|
||||||
uint_set m_in_coi;
|
uint_set m_in_coi;
|
||||||
vector<std::tuple<literal_vector, clause*, bool, bool>> m_trail;
|
vector<std::tuple<unsigned, literal_vector, clause*, bool, bool>> m_trail;
|
||||||
|
|
||||||
|
|
||||||
struct hash {
|
struct hash {
|
||||||
|
@ -49,6 +49,7 @@ namespace sat {
|
||||||
map<literal_vector, clause_vector, hash, eq> m_clauses;
|
map<literal_vector, clause_vector, hash, eq> m_clauses;
|
||||||
|
|
||||||
hashtable<literal_vector, hash, eq> m_core_literals;
|
hashtable<literal_vector, hash, eq> m_core_literals;
|
||||||
|
bool_vector m_propagated;
|
||||||
|
|
||||||
void del(literal_vector const& cl, clause* cp);
|
void del(literal_vector const& cl, clause* cp);
|
||||||
|
|
||||||
|
@ -57,6 +58,8 @@ namespace sat {
|
||||||
|
|
||||||
void prune_trail(literal_vector const& cl, clause* cp);
|
void prune_trail(literal_vector const& cl, clause* cp);
|
||||||
void conflict_analysis_core(literal_vector const& cl, clause* cp);
|
void conflict_analysis_core(literal_vector const& cl, clause* cp);
|
||||||
|
void add_dependency(literal lit);
|
||||||
|
void add_dependency(justification j);
|
||||||
void add_core(literal l, justification j);
|
void add_core(literal l, justification j);
|
||||||
bool in_core(literal_vector const& cl, clause* cp) const;
|
bool in_core(literal_vector const& cl, clause* cp) const;
|
||||||
void revive(literal_vector const& cl, clause* cp);
|
void revive(literal_vector const& cl, clause* cp);
|
||||||
|
@ -73,12 +76,12 @@ namespace sat {
|
||||||
void add_literal(bool_var v, bool sign) { m_clause.push_back(literal(v, sign)); }
|
void add_literal(bool_var v, bool sign) { m_clause.push_back(literal(v, sign)); }
|
||||||
unsigned num_vars() { return s.num_vars(); }
|
unsigned num_vars() { return s.num_vars(); }
|
||||||
|
|
||||||
void assume(bool is_initial = true);
|
void assume(unsigned id, bool is_initial = true);
|
||||||
void del();
|
void del();
|
||||||
void infer();
|
void infer(unsigned id);
|
||||||
void updt_params(params_ref const& p) { s.updt_params(p); }
|
void updt_params(params_ref const& p) { s.updt_params(p); }
|
||||||
|
|
||||||
vector<literal_vector> trim();
|
unsigned_vector trim();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue