mirror of
https://github.com/Z3Prover/z3
synced 2025-05-13 02:34:43 +00:00
Polysat: conflict explanation prototype (#5353)
* display constraint's extra info in one place * Add stub for conflict explainer * Add helper functions to check whether constraint is active at base level * Add helper class tmp_assign * Add clause_builder; it skips unnecessary literals during clause creation * some fixes * Use clause_builder for forbidden intervals * remove old comments * fixes/comments in solver * print redundant clauses * First pass at conflict_explainer * remove unused model class * Choose value for k * also print min/max k
This commit is contained in:
parent
1fe7dc40fe
commit
3e1cfcd538
11 changed files with 449 additions and 60 deletions
|
@ -99,21 +99,20 @@ namespace polysat {
|
|||
// => the side conditions of that interval are enough to produce a conflict
|
||||
auto& full_record = records.back();
|
||||
SASSERT(full_record.interval.is_full());
|
||||
sat::literal_vector literals;
|
||||
constraint_ref_vector new_constraints;
|
||||
literals.push_back(~full_record.src->blit()); // TODO: only do this if it's not a base-level constraint! (from unit clauses, e.g., external constraints)
|
||||
if (full_record.neg_cond) {
|
||||
literals.push_back(sat::literal(full_record.neg_cond.get()->bvar()));
|
||||
new_constraints.push_back(std::move(full_record.neg_cond));
|
||||
}
|
||||
clause_builder clause(s);
|
||||
clause.push_literal(~full_record.src->blit());
|
||||
if (full_record.neg_cond)
|
||||
clause.push_new_constraint(std::move(full_record.neg_cond));
|
||||
unsigned lemma_lvl = full_record.src->level();
|
||||
p_dependency_ref lemma_dep(full_record.src->dep(), s.m_dm);
|
||||
out_lemma = clause::from_literals(lemma_lvl, lemma_dep, std::move(literals), std::move(new_constraints));
|
||||
out_lemma = clause.build(lemma_lvl, lemma_dep);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (records.empty())
|
||||
if (records.empty()) {
|
||||
LOG("aborted (no intervals)");
|
||||
return false;
|
||||
}
|
||||
|
||||
SASSERT(longest_i != UINT_MAX);
|
||||
LOG("longest: i=" << longest_i << "; " << records[longest_i].interval);
|
||||
|
@ -123,6 +122,7 @@ namespace polysat {
|
|||
// Select a sequence of covering intervals
|
||||
unsigned_vector seq;
|
||||
if (!find_covering_sequence(records, longest_i, modulus, seq)) {
|
||||
LOG("aborted (intervals do not cover domain)");
|
||||
return false;
|
||||
}
|
||||
LOG("seq: " << seq);
|
||||
|
@ -145,14 +145,11 @@ namespace polysat {
|
|||
// then the forbidden intervals cover the whole domain and we have a conflict.
|
||||
// We learn the negation of this conjunction.
|
||||
|
||||
sat::literal_vector literals;
|
||||
constraint_ref_vector new_constraints;
|
||||
clause_builder clause(s);
|
||||
// Add negation of src constraints as antecedents (may be resolved during backtracking)
|
||||
for (unsigned const i : seq) {
|
||||
// TODO: don't add base-level constraints! (from unit clauses, e.g., external constraints)
|
||||
// (maybe extract that into a helper function on 'clause'... it could sort out base-level and other constraints; add the first to lemma_dep and the other to antecedents)
|
||||
sat::literal src_lit = records[i].src->blit();
|
||||
literals.push_back(~src_lit);
|
||||
clause.push_literal(~src_lit);
|
||||
}
|
||||
// Add side conditions and interval constraints
|
||||
for (unsigned seq_i = seq.size(); seq_i-- > 0; ) {
|
||||
|
@ -167,17 +164,14 @@ namespace polysat {
|
|||
auto const& rhs = next_hi - next_lo;
|
||||
constraint_ref c = s.m_constraints.ult(lemma_lvl, neg_t, lhs, rhs, s.mk_dep_ref(null_dependency));
|
||||
LOG("constraint: " << *c);
|
||||
literals.push_back(sat::literal(c->bvar()));
|
||||
new_constraints.push_back(std::move(c));
|
||||
clause.push_new_constraint(std::move(c));
|
||||
// Side conditions
|
||||
// TODO: check whether the condition is subsumed by c? maybe at the end do a "lemma reduction" step, to try and reduce branching?
|
||||
constraint_ref& neg_cond = records[i].neg_cond;
|
||||
if (neg_cond) {
|
||||
literals.push_back(sat::literal(neg_cond->bvar()));
|
||||
new_constraints.push_back(std::move(neg_cond));
|
||||
}
|
||||
if (neg_cond)
|
||||
clause.push_new_constraint(std::move(neg_cond));
|
||||
}
|
||||
out_lemma = clause::from_literals(lemma_lvl, lemma_dep, std::move(literals), std::move(new_constraints));
|
||||
out_lemma = clause.build(lemma_lvl, lemma_dep);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue