mirror of
https://github.com/Z3Prover/z3
synced 2025-07-03 03:15:41 +00:00
fixes
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a574eebd05
commit
95e2d174c7
5 changed files with 37 additions and 23 deletions
|
@ -90,7 +90,7 @@ namespace polysat {
|
||||||
SASSERT(empty());
|
SASSERT(empty());
|
||||||
m_conflict_var = v;
|
m_conflict_var = v;
|
||||||
for (auto c : s.m_cjust[v]) {
|
for (auto c : s.m_cjust[v]) {
|
||||||
c->set_var_dependent();
|
c->set_var_dependent(); // ??
|
||||||
insert(c);
|
insert(c);
|
||||||
}
|
}
|
||||||
SASSERT(!empty());
|
SASSERT(!empty());
|
||||||
|
@ -103,8 +103,8 @@ namespace polysat {
|
||||||
LOG("Conflict: " << cl);
|
LOG("Conflict: " << cl);
|
||||||
SASSERT(empty());
|
SASSERT(empty());
|
||||||
for (auto lit : cl) {
|
for (auto lit : cl) {
|
||||||
auto c = s.lit2cnstr(lit);
|
auto c = s.lit2cnstr(lit);
|
||||||
c->set_var_dependent();
|
// no c->set_var_dependent();
|
||||||
insert(~c);
|
insert(~c);
|
||||||
}
|
}
|
||||||
SASSERT(!empty());
|
SASSERT(!empty());
|
||||||
|
|
|
@ -78,8 +78,9 @@ namespace polysat {
|
||||||
// solver handles unsat clauses by creating a conflict.
|
// solver handles unsat clauses by creating a conflict.
|
||||||
// solver also can propagate, but need to check that it does indeed.
|
// solver also can propagate, but need to check that it does indeed.
|
||||||
void constraint_manager::watch(clause& cl, solver& s) {
|
void constraint_manager::watch(clause& cl, solver& s) {
|
||||||
if (cl.size() <= 1)
|
if (cl.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (unsigned i = 0; i < cl.size(); ++i) {
|
for (unsigned i = 0; i < cl.size(); ++i) {
|
||||||
if (m_bvars.is_false(cl[i]))
|
if (m_bvars.is_false(cl[i]))
|
||||||
|
@ -93,7 +94,8 @@ namespace polysat {
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
m_bvars.watch(cl[0]).push_back(&cl);
|
m_bvars.watch(cl[0]).push_back(&cl);
|
||||||
m_bvars.watch(cl[1]).push_back(&cl);
|
if (cl.size() > 1)
|
||||||
|
m_bvars.watch(cl[1]).push_back(&cl);
|
||||||
if (m_bvars.is_true(cl[0]))
|
if (m_bvars.is_true(cl[0]))
|
||||||
return;
|
return;
|
||||||
if (first)
|
if (first)
|
||||||
|
|
|
@ -137,6 +137,7 @@ namespace polysat {
|
||||||
lbool m_external_sign = l_undef;
|
lbool m_external_sign = l_undef;
|
||||||
bool m_is_marked = false;
|
bool m_is_marked = false;
|
||||||
bool m_is_var_dependent = false;
|
bool m_is_var_dependent = false;
|
||||||
|
bool m_is_active = false;
|
||||||
/** The boolean variable associated to this constraint, if any.
|
/** The boolean variable associated to this constraint, if any.
|
||||||
* If this is not null_bool_var, then the constraint corresponds to a literal on the assignment stack.
|
* If this is not null_bool_var, then the constraint corresponds to a literal on the assignment stack.
|
||||||
* Convention: the plain constraint corresponds the positive sat::literal.
|
* Convention: the plain constraint corresponds the positive sat::literal.
|
||||||
|
@ -189,7 +190,10 @@ namespace polysat {
|
||||||
|
|
||||||
void set_var_dependent() { m_is_var_dependent = true; }
|
void set_var_dependent() { m_is_var_dependent = true; }
|
||||||
void unset_var_dependent() { m_is_var_dependent = false; }
|
void unset_var_dependent() { m_is_var_dependent = false; }
|
||||||
bool is_var_dependent() { return m_is_var_dependent; }
|
bool is_var_dependent() const { return m_is_var_dependent; }
|
||||||
|
|
||||||
|
bool is_active() const { return m_is_active; }
|
||||||
|
void set_active(bool f) { m_is_active = f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }
|
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }
|
||||||
|
|
|
@ -161,7 +161,7 @@ namespace polysat {
|
||||||
* Propagate assignment to a Boolean variable
|
* Propagate assignment to a Boolean variable
|
||||||
*/
|
*/
|
||||||
void solver::propagate(sat::literal lit) {
|
void solver::propagate(sat::literal lit) {
|
||||||
LOG_H2("Propagate bool " << lit);
|
LOG_H2("Propagate bool " << lit << "@" << m_bvars.level(lit) << " " << m_level << " qhead: " << m_qhead);
|
||||||
signed_constraint c = lit2cnstr(lit);
|
signed_constraint c = lit2cnstr(lit);
|
||||||
SASSERT(c);
|
SASSERT(c);
|
||||||
activate_constraint(c);
|
activate_constraint(c);
|
||||||
|
@ -192,22 +192,23 @@ namespace polysat {
|
||||||
|
|
||||||
bool solver::propagate(sat::literal lit, clause& cl) {
|
bool solver::propagate(sat::literal lit, clause& cl) {
|
||||||
SASSERT(cl.size() >= 2);
|
SASSERT(cl.size() >= 2);
|
||||||
|
std::cout << lit << ": " << cl << "\n";
|
||||||
unsigned idx = cl[0] == ~lit ? 1 : 0;
|
unsigned idx = cl[0] == ~lit ? 1 : 0;
|
||||||
SASSERT(cl[1 - idx] == ~lit);
|
SASSERT(cl[1 - idx] == ~lit);
|
||||||
if (m_bvars.is_true(cl[idx]))
|
if (m_bvars.is_true(cl[idx]))
|
||||||
return true;
|
return false;
|
||||||
unsigned i = 2;
|
unsigned i = 2;
|
||||||
for (; i < cl.size() && m_bvars.is_false(cl[i]); ++i);
|
for (; i < cl.size() && m_bvars.is_false(cl[i]); ++i);
|
||||||
if (i < cl.size()) {
|
if (i < cl.size()) {
|
||||||
m_bvars.watch(cl[i]).push_back(&cl);
|
m_bvars.watch(cl[i]).push_back(&cl);
|
||||||
std::swap(cl[1 - idx], cl[i]);
|
std::swap(cl[1 - idx], cl[i]);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
if (m_bvars.is_false(cl[idx]))
|
if (m_bvars.is_false(cl[idx]))
|
||||||
set_conflict(cl);
|
set_conflict(cl);
|
||||||
else
|
else
|
||||||
assign_bool(level(cl), cl[idx], &cl, nullptr);
|
assign_bool(level(cl), cl[idx], &cl, nullptr);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::linear_propagate() {
|
void solver::linear_propagate() {
|
||||||
|
@ -254,9 +255,6 @@ namespace polysat {
|
||||||
switch (m_trail.back()) {
|
switch (m_trail.back()) {
|
||||||
case trail_instr_t::qhead_i: {
|
case trail_instr_t::qhead_i: {
|
||||||
pop_qhead();
|
pop_qhead();
|
||||||
for (unsigned i = m_search.size(); i-- > m_qhead; )
|
|
||||||
if (m_search[i].is_boolean())
|
|
||||||
deactivate_constraint(lit2cnstr(m_search[i].lit()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case trail_instr_t::add_var_i: {
|
case trail_instr_t::add_var_i: {
|
||||||
|
@ -282,12 +280,17 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
case trail_instr_t::assign_bool_i: {
|
case trail_instr_t::assign_bool_i: {
|
||||||
sat::literal lit = m_search.back().lit();
|
sat::literal lit = m_search.back().lit();
|
||||||
|
signed_constraint c = lit2cnstr(lit);
|
||||||
LOG_V("Undo assign_bool_i: " << lit);
|
LOG_V("Undo assign_bool_i: " << lit);
|
||||||
unsigned active_level = m_bvars.level(lit);
|
unsigned active_level = m_bvars.level(lit);
|
||||||
|
|
||||||
|
if (c->is_active())
|
||||||
|
deactivate_constraint(c);
|
||||||
|
|
||||||
if (active_level <= target_level)
|
if (active_level <= target_level)
|
||||||
replay.push_back(lit);
|
replay.push_back(lit);
|
||||||
else
|
else
|
||||||
m_bvars.unassign(lit);
|
m_bvars.unassign(lit);
|
||||||
m_search.pop();
|
m_search.pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -454,8 +457,6 @@ namespace polysat {
|
||||||
revert_decision(v);
|
revert_decision(v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//SASSERT(j.is_propagation());
|
|
||||||
//resolve_value(v);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Resolve over boolean literal
|
// Resolve over boolean literal
|
||||||
|
@ -484,12 +485,12 @@ namespace polysat {
|
||||||
return m_conflict.resolve_value(v, m_cjust[v]);
|
return m_conflict.resolve_value(v, m_cjust[v]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Conflict resolution case where boolean literal 'lit' is on top of the stack */
|
/** Conflict resolution case where boolean literal 'lit' is on top of the stack
|
||||||
|
* NOTE: boolean resolution should work normally even in bailout mode.
|
||||||
|
*/
|
||||||
void solver::resolve_bool(sat::literal lit) {
|
void solver::resolve_bool(sat::literal lit) {
|
||||||
sat::bool_var const var = lit.var();
|
SASSERT(m_bvars.is_propagation(lit.var()));
|
||||||
SASSERT(m_bvars.is_propagation(var));
|
clause other = *m_bvars.reason(lit.var());
|
||||||
// NOTE: boolean resolution should work normally even in bailout mode.
|
|
||||||
clause other = *m_bvars.reason(var);
|
|
||||||
LOG_H3("resolve_bool: " << lit << " " << other);
|
LOG_H3("resolve_bool: " << lit << " " << other);
|
||||||
m_conflict.resolve(m_constraints, lit, other);
|
m_conflict.resolve(m_constraints, lit, other);
|
||||||
}
|
}
|
||||||
|
@ -635,6 +636,7 @@ namespace polysat {
|
||||||
// - drawback: might have to bail out at boolean resolution
|
// - drawback: might have to bail out at boolean resolution
|
||||||
// Also: maybe we can skip ~L in some cases? but in that case it shouldn't be marked.
|
// Also: maybe we can skip ~L in some cases? but in that case it shouldn't be marked.
|
||||||
//
|
//
|
||||||
|
std::cout << "ADD extra " << ~lit << "\n";
|
||||||
reason_builder.push(~lit);
|
reason_builder.push(~lit);
|
||||||
}
|
}
|
||||||
clause_ref reason = reason_builder.build();
|
clause_ref reason = reason_builder.build();
|
||||||
|
@ -700,6 +702,8 @@ namespace polysat {
|
||||||
SASSERT(c);
|
SASSERT(c);
|
||||||
LOG("Activating constraint: " << c);
|
LOG("Activating constraint: " << c);
|
||||||
SASSERT(m_bvars.value(c.blit()) == l_true);
|
SASSERT(m_bvars.value(c.blit()) == l_true);
|
||||||
|
SASSERT(!c->is_active());
|
||||||
|
c->set_active(true);
|
||||||
add_watch(c);
|
add_watch(c);
|
||||||
c.narrow(*this);
|
c.narrow(*this);
|
||||||
#if ENABLE_LINEAR_SOLVER
|
#if ENABLE_LINEAR_SOLVER
|
||||||
|
@ -709,7 +713,8 @@ namespace polysat {
|
||||||
|
|
||||||
/// Deactivate constraint
|
/// Deactivate constraint
|
||||||
void solver::deactivate_constraint(signed_constraint c) {
|
void solver::deactivate_constraint(signed_constraint c) {
|
||||||
LOG("Deactivating constraint: " << c);
|
LOG("Deactivating constraint: " << c.blit());
|
||||||
|
c->set_active(false);
|
||||||
erase_watch(c);
|
erase_watch(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1047,6 +1047,9 @@ namespace polysat {
|
||||||
|
|
||||||
void tst_polysat() {
|
void tst_polysat() {
|
||||||
|
|
||||||
|
polysat::test_ineq_basic4();
|
||||||
|
return;
|
||||||
|
|
||||||
polysat::test_p3();
|
polysat::test_p3();
|
||||||
|
|
||||||
polysat::test_var_minimize();
|
polysat::test_var_minimize();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue