mirror of
https://github.com/Z3Prover/z3
synced 2025-07-03 11:25:40 +00:00
Add support for bailout lemma
This commit is contained in:
parent
f2c79b851f
commit
a0570908fb
5 changed files with 28 additions and 21 deletions
|
@ -17,8 +17,13 @@ Author:
|
||||||
|
|
||||||
namespace polysat {
|
namespace polysat {
|
||||||
|
|
||||||
|
static_assert(!std::is_copy_assignable_v<clause_builder>);
|
||||||
|
static_assert(!std::is_copy_constructible_v<clause_builder>);
|
||||||
|
static_assert(std::is_move_assignable_v<clause_builder>);
|
||||||
|
static_assert(std::is_move_constructible_v<clause_builder>);
|
||||||
|
|
||||||
clause_builder::clause_builder(solver& s):
|
clause_builder::clause_builder(solver& s):
|
||||||
m_solver(s), m_dep(nullptr, s.m_dm)
|
m_solver(&s), m_dep(nullptr, s.m_dm)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void clause_builder::reset() {
|
void clause_builder::reset() {
|
||||||
|
@ -29,7 +34,6 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
clause_ref clause_builder::build() {
|
clause_ref clause_builder::build() {
|
||||||
// TODO: here we could set all the levels of the new constraints. so we do not have to compute the max at every use site.
|
|
||||||
clause_ref cl = clause::from_literals(m_level, std::move(m_dep), std::move(m_literals));
|
clause_ref cl = clause::from_literals(m_level, std::move(m_dep), std::move(m_literals));
|
||||||
m_level = 0;
|
m_level = 0;
|
||||||
SASSERT(empty());
|
SASSERT(empty());
|
||||||
|
@ -37,11 +41,11 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void clause_builder::add_dependency(p_dependency* d) {
|
void clause_builder::add_dependency(p_dependency* d) {
|
||||||
m_dep = m_solver.m_dm.mk_join(m_dep, d);
|
m_dep = m_solver->m_dm.mk_join(m_dep, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clause_builder::push_literal(sat::literal lit) {
|
void clause_builder::push(sat::literal lit) {
|
||||||
push(m_solver.m_constraints.lookup(lit));
|
push(m_solver->m_constraints.lookup(lit));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clause_builder::push(signed_constraint c) {
|
void clause_builder::push(signed_constraint c) {
|
||||||
|
|
|
@ -25,13 +25,17 @@ namespace polysat {
|
||||||
|
|
||||||
// TODO: this is now incorporated in conflict_core
|
// TODO: this is now incorporated in conflict_core
|
||||||
class clause_builder {
|
class clause_builder {
|
||||||
solver& m_solver;
|
solver* m_solver;
|
||||||
sat::literal_vector m_literals;
|
sat::literal_vector m_literals;
|
||||||
p_dependency_ref m_dep;
|
p_dependency_ref m_dep;
|
||||||
unsigned m_level = 0;
|
unsigned m_level = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
clause_builder(solver& s);
|
clause_builder(solver& s);
|
||||||
|
clause_builder(clause_builder const& s) = delete;
|
||||||
|
clause_builder(clause_builder&& s) = default;
|
||||||
|
clause_builder& operator=(clause_builder const& s) = delete;
|
||||||
|
clause_builder& operator=(clause_builder&& s) = default;
|
||||||
|
|
||||||
bool empty() const { return m_literals.empty() && m_dep == nullptr && m_level == 0; }
|
bool empty() const { return m_literals.empty() && m_dep == nullptr && m_level == 0; }
|
||||||
void reset();
|
void reset();
|
||||||
|
@ -43,15 +47,9 @@ namespace polysat {
|
||||||
|
|
||||||
void add_dependency(p_dependency* d);
|
void add_dependency(p_dependency* d);
|
||||||
|
|
||||||
/// Add a literal to the clause.
|
void push(sat::literal lit);
|
||||||
/// Intended to be used for literals representing a constraint that already exists.
|
|
||||||
void push_literal(sat::literal lit);
|
|
||||||
|
|
||||||
void push(signed_constraint c);
|
void push(signed_constraint c);
|
||||||
|
|
||||||
/// Add a constraint to the clause that does not yet exist in the solver so far.
|
|
||||||
// void push_new_constraint(signed_constraint c);
|
|
||||||
|
|
||||||
using const_iterator = decltype(m_literals)::const_iterator;
|
using const_iterator = decltype(m_literals)::const_iterator;
|
||||||
const_iterator begin() const { return m_literals.begin(); }
|
const_iterator begin() const { return m_literals.begin(); }
|
||||||
const_iterator end() const { return m_literals.end(); }
|
const_iterator end() const { return m_literals.end(); }
|
||||||
|
|
|
@ -149,10 +149,10 @@ namespace polysat {
|
||||||
clause_builder c_lemma(*m_solver);
|
clause_builder c_lemma(*m_solver);
|
||||||
for (auto premise : premises) {
|
for (auto premise : premises) {
|
||||||
handle_saturation_premises(premise);
|
handle_saturation_premises(premise);
|
||||||
c_lemma.push_literal(~premise.blit());
|
c_lemma.push(~premise.blit());
|
||||||
active_level = std::max(active_level, m_solver->m_bvars.level(premise.blit()));
|
active_level = std::max(active_level, m_solver->m_bvars.level(premise.blit()));
|
||||||
}
|
}
|
||||||
c_lemma.push_literal(c.blit());
|
c_lemma.push(c.blit());
|
||||||
clause* cl = cm().store(c_lemma.build());
|
clause* cl = cm().store(c_lemma.build());
|
||||||
if (cl->size() == 1)
|
if (cl->size() == 1)
|
||||||
c->set_unit_clause(cl);
|
c->set_unit_clause(cl);
|
||||||
|
@ -180,10 +180,10 @@ namespace polysat {
|
||||||
pvar v = item.var();
|
pvar v = item.var();
|
||||||
auto c = ~cm().eq(0, m_solver->var(v) - m_solver->m_value[v]);
|
auto c = ~cm().eq(0, m_solver->var(v) - m_solver->m_value[v]);
|
||||||
cm().ensure_bvar(c.get());
|
cm().ensure_bvar(c.get());
|
||||||
lemma.push_literal(c.blit());
|
lemma.push(c.blit());
|
||||||
} else {
|
} else {
|
||||||
sat::literal lit = item.lit();
|
sat::literal lit = item.lit();
|
||||||
lemma.push_literal(~lit);
|
lemma.push(~lit);
|
||||||
}
|
}
|
||||||
--todo;
|
--todo;
|
||||||
}
|
}
|
||||||
|
@ -228,10 +228,12 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
clause_builder conflict_core::build_lemma(unsigned reverted_level) {
|
clause_builder conflict_core::build_lemma(unsigned reverted_level) {
|
||||||
if (is_bailout())
|
if (!is_bailout())
|
||||||
return build_fallback_lemma(reverted_level);
|
|
||||||
else
|
|
||||||
return build_core_lemma(reverted_level);
|
return build_core_lemma(reverted_level);
|
||||||
|
else if (m_bailout_lemma)
|
||||||
|
return *std::move(m_bailout_lemma);
|
||||||
|
else
|
||||||
|
return build_fallback_lemma(reverted_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool conflict_core::resolve_value(pvar v, vector<signed_constraint> const& cjust_v) {
|
bool conflict_core::resolve_value(pvar v, vector<signed_constraint> const& cjust_v) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ Author:
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "math/polysat/constraint.h"
|
#include "math/polysat/constraint.h"
|
||||||
#include "math/polysat/clause_builder.h"
|
#include "math/polysat/clause_builder.h"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace polysat {
|
namespace polysat {
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ namespace polysat {
|
||||||
|
|
||||||
/** Whether we are in a bailout state. We enter a bailout state when we give up on proper conflict resolution. */
|
/** Whether we are in a bailout state. We enter a bailout state when we give up on proper conflict resolution. */
|
||||||
bool m_bailout = false;
|
bool m_bailout = false;
|
||||||
|
std::optional<clause_builder> m_bailout_lemma;
|
||||||
|
|
||||||
solver* m_solver = nullptr;
|
solver* m_solver = nullptr;
|
||||||
constraint_manager& cm();
|
constraint_manager& cm();
|
||||||
|
@ -69,6 +71,7 @@ namespace polysat {
|
||||||
m_conflict_var = null_var;
|
m_conflict_var = null_var;
|
||||||
m_saturation_premises.reset();
|
m_saturation_premises.reset();
|
||||||
m_bailout = false;
|
m_bailout = false;
|
||||||
|
m_bailout_lemma.reset();
|
||||||
SASSERT(empty());
|
SASSERT(empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -713,7 +713,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.
|
||||||
//
|
//
|
||||||
reason_builder.push_literal(~lit);
|
reason_builder.push(~lit);
|
||||||
}
|
}
|
||||||
clause_ref reason = reason_builder.build();
|
clause_ref reason = reason_builder.build();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue