16 #ifndef OR_TOOLS_SAT_SAT_BASE_H_
17 #define OR_TOOLS_SAT_SAT_BASE_H_
29 #include "absl/base/attributes.h"
30 #include "absl/strings/str_format.h"
31 #include "absl/strings/string_view.h"
32 #include "absl/types/span.h"
75 : index_(signed_value > 0 ? ((signed_value - 1) << 1)
76 : ((-signed_value - 1) << 1) ^ 1) {
77 CHECK_NE(signed_value, 0);
82 Literal(BooleanVariable variable,
bool is_positive)
83 : index_(is_positive ? (variable.
value() << 1)
84 : (variable.
value() << 1) ^ 1) {}
86 BooleanVariable
Variable()
const {
return BooleanVariable(index_ >> 1); }
90 LiteralIndex
Index()
const {
return LiteralIndex(index_); }
91 LiteralIndex
NegatedIndex()
const {
return LiteralIndex(index_ ^ 1); }
94 return (index_ & 1) ? -((index_ >> 1) + 1) : ((index_ >> 1) + 1);
119 absl::Span<const Literal> literals) {
141 assignment_.
Resize(LiteralIndex(num_variables << 1));
225 return absl::StrFormat(
"level:%d type:%d trail_index:%d",
level,
type,
229 static_assert(
sizeof(AssignmentInfo) == 8,
230 "ERROR_AssignmentInfo_is_not_well_compacted");
251 current_info_.
level = 0;
254 void Resize(
int num_variables);
265 current_info_.
type = propagator_id;
266 info_[true_literal.
Variable()] = current_info_;
285 BooleanVariable reference_var) {
286 reference_var_with_same_reason_as_[true_literal.
Variable()] = reference_var;
305 const BooleanVariable
var = true_literal.
Variable();
306 reasons_[
var] = reasons_repository_[info_[
var].trail_index];
307 old_type_[
var] = info_[
var].type;
317 absl::Span<const Literal>
Reason(BooleanVariable
var)
const;
333 if (trail_index >= reasons_repository_.size()) {
334 reasons_repository_.resize(trail_index + 1);
336 reasons_repository_[trail_index].clear();
337 return &reasons_repository_[trail_index];
348 const BooleanVariable
var = trail_[trail_index].Variable();
349 info_[
var].type = propagator_id;
350 old_type_[
var] = propagator_id;
357 num_untrailed_enqueues_ +=
index - target_trail_index;
358 for (
int i = target_trail_index; i <
index; ++i) {
374 failing_sat_clause_ =
nullptr;
380 if (
DEBUG_MODE && debug_checker_ !=
nullptr) {
381 debug_checker_(conflict_);
399 return trail_.begin() +
index;
405 DCHECK_LT(
var, info_.size());
412 for (
int i = 0; i < current_info_.
trail_index; ++i) {
413 if (!result.empty()) result +=
" ";
414 result += trail_[i].DebugString();
420 std::function<
bool(absl::Span<const Literal> clause)> checker) {
421 debug_checker_ = std::move(checker);
425 int64_t num_untrailed_enqueues_ = 0;
428 std::vector<Literal> trail_;
429 std::vector<Literal> conflict_;
435 reference_var_with_same_reason_as_;
460 mutable std::deque<std::vector<Literal>> reasons_repository_;
466 std::vector<SatPropagator*> propagators_;
468 std::function<bool(absl::Span<const Literal> clause)> debug_checker_ =
471 DISALLOW_COPY_AND_ASSIGN(
Trail);
520 int trail_index)
const {
521 LOG(FATAL) <<
"Not implemented.";
538 virtual bool IsEmpty()
const {
return false; }
554 const Trail& trail)
const {
556 LOG(INFO) <<
"Issue in '" <<
name_ <<
":"
558 <<
" trail_.Index()=" << trail.
Index();
564 LOG(INFO) <<
"Issue in '" <<
name_ <<
"':"
566 <<
" trail_.Index()=" << trail.
Index()
567 <<
" level_at_propagation_index="
576 assignment_.
Resize(num_variables);
577 info_.resize(num_variables);
578 trail_.resize(num_variables);
579 reasons_.resize(num_variables);
583 old_type_.
resize(num_variables);
584 reference_var_with_same_reason_as_.
resize(num_variables);
588 if (propagators_.empty()) {
591 CHECK_LT(propagators_.size(), 16);
593 propagators_.push_back(propagator);
597 BooleanVariable
var)
const {
601 var = reference_var_with_same_reason_as_[
var];
610 var = reference_var_with_same_reason_as_[
var];
613 const int type = info_[
var].type;
623 if (
DEBUG_MODE && debug_checker_ !=
nullptr) {
624 std::vector<Literal> clause;
625 clause.assign(reasons_[
var].begin(), reasons_[
var].
end());
627 debug_checker_(clause);
629 return reasons_[
var];
637 DCHECK_LT(info.
type, propagators_.size());
638 DCHECK(propagators_[info.
type] !=
nullptr) << info.
type;
643 if (
DEBUG_MODE && debug_checker_ !=
nullptr) {
644 std::vector<Literal> clause;
645 clause.assign(reasons_[
var].begin(), reasons_[
var].
end());
647 debug_checker_(clause);
649 return reasons_[
var];
void resize(size_type new_size)
void Resize(IndexType size)
bool IsSet(IndexType i) const
void ClearTwoBits(IndexType i)
bool AreOneOfTwoBitsSet(IndexType i) const
Literal(int signed_value)
LiteralIndex NegatedIndex() const
LiteralIndex Index() const
Literal(LiteralIndex index)
Literal(BooleanVariable variable, bool is_positive)
BooleanVariable Variable() const
std::string DebugString() const
bool operator==(Literal other) const
bool operator!=(Literal other) const
bool operator<(const Literal &literal) const
int propagation_trail_index_
void SetPropagatorId(int id)
virtual bool Propagate(Trail *trail)=0
SatPropagator(const std::string &name)
virtual absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const
bool PropagatePreconditionsAreSatisfied(const Trail &trail) const
virtual void Untrail(const Trail &trail, int trail_index)
virtual bool IsEmpty() const
bool PropagationIsDone(const Trail &trail) const
absl::Span< const Literal > FailingClause() const
void RegisterPropagator(SatPropagator *propagator)
void Enqueue(Literal true_literal, int propagator_id)
const Literal & operator[](int index) const
void ChangeReason(int trail_index, int propagator_id)
const AssignmentInfo & Info(BooleanVariable var) const
int64_t NumberOfEnqueues() const
SatClause * FailingSatClause() const
void EnqueueWithSameReasonAs(Literal true_literal, BooleanVariable reference_var)
int AssignmentType(BooleanVariable var) const
std::string DebugString()
std::vector< Literal > * GetEmptyVectorToStoreReason(int trail_index) const
std::vector< Literal > * GetEmptyVectorToStoreReason() const
void SetFailingSatClause(SatClause *clause)
std::vector< Literal > * MutableConflict()
absl::Span< const Literal > Reason(BooleanVariable var) const
BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const
void RegisterDebugChecker(std::function< bool(absl::Span< const Literal > clause)> checker)
const VariablesAssignment & Assignment() const
ABSL_MUST_USE_RESULT bool EnqueueWithStoredReason(Literal true_literal)
void Untrail(int target_trail_index)
int CurrentDecisionLevel() const
const std::vector< Literal >::const_iterator IteratorAt(int index) const
void SetDecisionLevel(int level)
void Resize(int num_variables)
void EnqueueWithUnitReason(Literal true_literal)
void EnqueueSearchDecision(Literal true_literal)
bool LiteralIsAssigned(Literal literal) const
bool VariableIsAssigned(BooleanVariable var) const
bool LiteralIsTrue(Literal literal) const
void AssignFromTrueLiteral(Literal literal)
void UnassignLiteral(Literal literal)
Literal GetTrueLiteralForAssignedVariable(BooleanVariable var) const
bool LiteralIsFalse(Literal literal) const
int NumberOfVariables() const
VariablesAssignment(int num_variables)
void Resize(int num_variables)
DEFINE_STRONG_INDEX_TYPE(ClauseIndex)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
const LiteralIndex kNoLiteralIndex(-1)
const LiteralIndex kTrueLiteralIndex(-2)
const LiteralIndex kFalseLiteralIndex(-3)
const BooleanVariable kNoBooleanVariable(-1)
Collection of objects used to extend the Constraint Solver library.
std::optional< int64_t > end
std::string DebugString() const
static constexpr int kUnitReason
static constexpr int kSameReasonAs
static constexpr int kFirstFreePropagationId
static constexpr int kSearchDecision
static constexpr int kCachedReason