mirror of
https://github.com/Z3Prover/z3
synced 2025-06-29 09:28:45 +00:00
Add separate state for deciding on lemmas
This commit is contained in:
parent
aea3545fcc
commit
0a48846add
2 changed files with 43 additions and 16 deletions
|
@ -75,6 +75,7 @@ namespace polysat {
|
||||||
else if (m_constraints.should_gc()) m_constraints.gc(*this);
|
else if (m_constraints.should_gc()) m_constraints.gc(*this);
|
||||||
else if (m_simplify.should_apply()) m_simplify();
|
else if (m_simplify.should_apply()) m_simplify();
|
||||||
else if (m_restart.should_apply()) m_restart();
|
else if (m_restart.should_apply()) m_restart();
|
||||||
|
else if (can_decide_on_lemma()) decide_on_lemma();
|
||||||
else decide();
|
else decide();
|
||||||
}
|
}
|
||||||
LOG_H2("UNDEF (resource limit)");
|
LOG_H2("UNDEF (resource limit)");
|
||||||
|
@ -201,9 +202,10 @@ namespace polysat {
|
||||||
void solver::propagate() {
|
void solver::propagate() {
|
||||||
if (!can_propagate())
|
if (!can_propagate())
|
||||||
return;
|
return;
|
||||||
if (m_propagating)
|
#ifndef NDEBUG
|
||||||
return;
|
SASSERT(!m_propagating);
|
||||||
m_propagating = true;
|
flet<bool> save_(m_propagating, true);
|
||||||
|
#endif
|
||||||
push_qhead();
|
push_qhead();
|
||||||
while (can_propagate()) {
|
while (can_propagate()) {
|
||||||
auto const& item = m_search[m_qhead++];
|
auto const& item = m_search[m_qhead++];
|
||||||
|
@ -215,7 +217,6 @@ namespace polysat {
|
||||||
linear_propagate();
|
linear_propagate();
|
||||||
SASSERT(wlist_invariant());
|
SASSERT(wlist_invariant());
|
||||||
SASSERT(assignment_invariant());
|
SASSERT(assignment_invariant());
|
||||||
m_propagating = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,6 +321,7 @@ namespace polysat {
|
||||||
#if ENABLE_LINEAR_SOLVER
|
#if ENABLE_LINEAR_SOLVER
|
||||||
m_linear_solver.pop(num_levels);
|
m_linear_solver.pop(num_levels);
|
||||||
#endif
|
#endif
|
||||||
|
drop_enqueued_lemma();
|
||||||
while (num_levels > 0) {
|
while (num_levels > 0) {
|
||||||
switch (m_trail.back()) {
|
switch (m_trail.back()) {
|
||||||
case trail_instr_t::qhead_i: {
|
case trail_instr_t::qhead_i: {
|
||||||
|
@ -598,12 +600,33 @@ namespace polysat {
|
||||||
LOG("Learning: "<< lemma);
|
LOG("Learning: "<< lemma);
|
||||||
SASSERT(!lemma.empty());
|
SASSERT(!lemma.empty());
|
||||||
add_clause(lemma);
|
add_clause(lemma);
|
||||||
if (!is_conflict())
|
enqueue_decision_on_lemma(lemma);
|
||||||
decide_bool(lemma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guess a literal from the given clause; returns the guessed constraint
|
void solver::enqueue_decision_on_lemma(clause& lemma) {
|
||||||
void solver::decide_bool(clause& lemma) {
|
m_lemmas.push_back(&lemma);
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::drop_enqueued_lemma() {
|
||||||
|
m_lemmas.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool solver::can_decide_on_lemma() {
|
||||||
|
return !m_lemmas.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::decide_on_lemma() {
|
||||||
|
SASSERT(!is_conflict());
|
||||||
|
SASSERT(m_lemmas.size() == 1); // we expect to only have a single one
|
||||||
|
// TODO: maybe it would be nicer to have a queue of lemmas, instead of storing lemmas per-literal in m_bvars?
|
||||||
|
while (!m_lemmas.empty()) {
|
||||||
|
clause* lemma = m_lemmas.back();
|
||||||
|
m_lemmas.pop_back();
|
||||||
|
decide_on_lemma(*lemma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::decide_on_lemma(clause& lemma) {
|
||||||
LOG_H3("Guessing literal in lemma: " << lemma);
|
LOG_H3("Guessing literal in lemma: " << lemma);
|
||||||
IF_LOGGING(m_viable.log());
|
IF_LOGGING(m_viable.log());
|
||||||
LOG("Boolean assignment: " << m_bvars);
|
LOG("Boolean assignment: " << m_bvars);
|
||||||
|
@ -718,10 +741,11 @@ namespace polysat {
|
||||||
|
|
||||||
backjump(m_bvars.level(var) - 1);
|
backjump(m_bvars.level(var) - 1);
|
||||||
|
|
||||||
|
// reason should force ~lit after propagation
|
||||||
add_clause(*reason);
|
add_clause(*reason);
|
||||||
|
|
||||||
if (!is_conflict() && lemma)
|
if (lemma) // TODO: can (should) this ever be NULL?
|
||||||
decide_bool(*lemma);
|
enqueue_decision_on_lemma(*lemma);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned solver::level(sat::literal lit0, clause const& cl) {
|
unsigned solver::level(sat::literal lit0, clause const& cl) {
|
||||||
|
@ -808,7 +832,6 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
SASSERT(!clause.empty());
|
SASSERT(!clause.empty());
|
||||||
m_constraints.store(&clause, *this);
|
m_constraints.store(&clause, *this);
|
||||||
propagate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_clause(unsigned n, signed_constraint* cs, bool is_redundant) {
|
void solver::add_clause(unsigned n, signed_constraint* cs, bool is_redundant) {
|
||||||
|
|
|
@ -105,8 +105,9 @@ namespace polysat {
|
||||||
vector<signed_constraints> m_pwatch; // watch list datastructure into constraints.
|
vector<signed_constraints> m_pwatch; // watch list datastructure into constraints.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::optional<pvar> m_locked_wlist; // restrict watch list modification while it is being propagated
|
std::optional<pvar> m_locked_wlist; // restrict watch list modification while it is being propagated
|
||||||
#endif
|
|
||||||
bool m_propagating = false; // set to true during propagation
|
bool m_propagating = false; // set to true during propagation
|
||||||
|
#endif
|
||||||
|
ptr_vector<clause> m_lemmas;
|
||||||
|
|
||||||
unsigned_vector m_activity;
|
unsigned_vector m_activity;
|
||||||
vector<pdd> m_vars;
|
vector<pdd> m_vars;
|
||||||
|
@ -155,15 +156,18 @@ namespace polysat {
|
||||||
void assign_eval(sat::literal lit);
|
void assign_eval(sat::literal lit);
|
||||||
void activate_constraint(signed_constraint c);
|
void activate_constraint(signed_constraint c);
|
||||||
void deactivate_constraint(signed_constraint c);
|
void deactivate_constraint(signed_constraint c);
|
||||||
void decide_bool(clause& lemma);
|
|
||||||
void decide_bool(sat::literal lit, clause* lemma);
|
|
||||||
unsigned level(sat::literal lit, clause const& cl);
|
unsigned level(sat::literal lit, clause const& cl);
|
||||||
|
|
||||||
|
bool can_decide_on_lemma();
|
||||||
|
void decide_on_lemma();
|
||||||
|
void decide_on_lemma(clause& lemma);
|
||||||
|
void enqueue_decision_on_lemma(clause& lemma);
|
||||||
|
void drop_enqueued_lemma();
|
||||||
|
|
||||||
void assign_core(pvar v, rational const& val, justification const& j);
|
void assign_core(pvar v, rational const& val, justification const& j);
|
||||||
bool is_assigned(pvar v) const { return !m_justification[v].is_unassigned(); }
|
bool is_assigned(pvar v) const { return !m_justification[v].is_unassigned(); }
|
||||||
bool is_decision(search_item const& item) const;
|
bool is_decision(search_item const& item) const;
|
||||||
|
|
||||||
|
|
||||||
bool should_search();
|
bool should_search();
|
||||||
|
|
||||||
void propagate(sat::literal lit);
|
void propagate(sat::literal lit);
|
||||||
|
@ -369,7 +373,7 @@ namespace polysat {
|
||||||
|
|
||||||
void updt_params(params_ref const& p);
|
void updt_params(params_ref const& p);
|
||||||
|
|
||||||
};
|
}; // class solver
|
||||||
|
|
||||||
class assignments_pp {
|
class assignments_pp {
|
||||||
solver const& s;
|
solver const& s;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue