OR-Tools  9.6
sat_base.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // Basic types and classes used by the sat solver.
15 
16 #ifndef OR_TOOLS_SAT_SAT_BASE_H_
17 #define OR_TOOLS_SAT_SAT_BASE_H_
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <deque>
22 #include <functional>
23 #include <memory>
24 #include <ostream>
25 #include <string>
26 #include <utility>
27 #include <vector>
28 
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"
34 #include "ortools/base/logging.h"
35 #include "ortools/base/macros.h"
37 #include "ortools/sat/model.h"
38 #include "ortools/util/bitset.h"
40 
41 namespace operations_research {
42 namespace sat {
43 
44 // Index of a variable (>= 0).
45 DEFINE_STRONG_INDEX_TYPE(BooleanVariable);
46 const BooleanVariable kNoBooleanVariable(-1);
47 
48 // Index of a literal (>= 0), see Literal below.
50 const LiteralIndex kNoLiteralIndex(-1);
51 
52 // Special values used in some API to indicate a literal that is always true
53 // or always false.
54 const LiteralIndex kTrueLiteralIndex(-2);
55 const LiteralIndex kFalseLiteralIndex(-3);
56 
57 // A literal is used to represent a variable or its negation. If it represents
58 // the variable it is said to be positive. If it represent its negation, it is
59 // said to be negative. We support two representations as an integer.
60 //
61 // The "signed" encoding of a literal is convenient for input/output and is used
62 // in the cnf file format. For a 0-based variable index x, (x + 1) represent the
63 // variable x and -(x + 1) represent its negation. The signed value 0 is an
64 // undefined literal and this class can never contain it.
65 //
66 // The "index" encoding of a literal is convenient as an index to an array
67 // and is the one used internally for efficiency. It is always positive or zero,
68 // and for a 0-based variable index x, (x << 1) encode the variable x and the
69 // same number XOR 1 encode its negation.
70 class Literal {
71  public:
72  // Not explicit for tests so we can write:
73  // vector<literal> literal = {+1, -3, +4, -9};
74  Literal(int signed_value) // NOLINT
75  : index_(signed_value > 0 ? ((signed_value - 1) << 1)
76  : ((-signed_value - 1) << 1) ^ 1) {
77  CHECK_NE(signed_value, 0);
78  }
79 
80  Literal() {}
81  explicit Literal(LiteralIndex index) : index_(index.value()) {}
82  Literal(BooleanVariable variable, bool is_positive)
83  : index_(is_positive ? (variable.value() << 1)
84  : (variable.value() << 1) ^ 1) {}
85 
86  BooleanVariable Variable() const { return BooleanVariable(index_ >> 1); }
87  bool IsPositive() const { return !(index_ & 1); }
88  bool IsNegative() const { return (index_ & 1); }
89 
90  LiteralIndex Index() const { return LiteralIndex(index_); }
91  LiteralIndex NegatedIndex() const { return LiteralIndex(index_ ^ 1); }
92 
93  int SignedValue() const {
94  return (index_ & 1) ? -((index_ >> 1) + 1) : ((index_ >> 1) + 1);
95  }
96 
97  Literal Negated() const { return Literal(NegatedIndex()); }
98 
99  std::string DebugString() const {
100  return absl::StrFormat("%+d", SignedValue());
101  }
102  bool operator==(Literal other) const { return index_ == other.index_; }
103  bool operator!=(Literal other) const { return index_ != other.index_; }
104 
105  bool operator<(const Literal& literal) const {
106  return Index() < literal.Index();
107  }
108 
109  private:
110  int index_;
111 };
112 
113 inline std::ostream& operator<<(std::ostream& os, Literal literal) {
114  os << literal.DebugString();
115  return os;
116 }
117 
118 inline std::ostream& operator<<(std::ostream& os,
119  absl::Span<const Literal> literals) {
120  os << "[";
121  bool first = true;
122  for (const Literal literal : literals) {
123  if (first) {
124  first = false;
125  } else {
126  os << ",";
127  }
128  os << literal.DebugString();
129  }
130  os << "]";
131  return os;
132 }
133 
134 // Holds the current variable assignment of the solver.
135 // Each variable can be unassigned or be assigned to true or false.
137  public:
139  explicit VariablesAssignment(int num_variables) { Resize(num_variables); }
140  void Resize(int num_variables) {
141  assignment_.Resize(LiteralIndex(num_variables << 1));
142  }
143 
144  // Makes the given literal true by assigning its underlying variable to either
145  // true or false depending on the literal sign. This can only be called on an
146  // unassigned variable.
148  DCHECK(!VariableIsAssigned(literal.Variable()));
149  assignment_.Set(literal.Index());
150  }
151 
152  // Unassign the variable corresponding to the given literal.
153  // This can only be called on an assigned variable.
155  DCHECK(VariableIsAssigned(literal.Variable()));
156  assignment_.ClearTwoBits(literal.Index());
157  }
158 
159  // Literal getters. Note that both can be false, in which case the
160  // corresponding variable is not assigned.
162  return assignment_.IsSet(literal.NegatedIndex());
163  }
165  return assignment_.IsSet(literal.Index());
166  }
168  return assignment_.AreOneOfTwoBitsSet(literal.Index());
169  }
170 
171  // Returns true iff the given variable is assigned.
172  bool VariableIsAssigned(BooleanVariable var) const {
173  return assignment_.AreOneOfTwoBitsSet(LiteralIndex(var.value() << 1));
174  }
175 
176  // Returns the literal of the given variable that is assigned to true.
177  // That is, depending on the variable, it can be the positive literal or the
178  // negative one. Only call this on an assigned variable.
180  DCHECK(VariableIsAssigned(var));
181  return Literal(var, assignment_.IsSet(LiteralIndex(var.value() << 1)));
182  }
183 
184  int NumberOfVariables() const { return assignment_.size().value() / 2; }
185 
186  private:
187  // The encoding is as follows:
188  // - assignment_.IsSet(literal.Index()) means literal is true.
189  // - assignment_.IsSet(literal.Index() ^ 1]) means literal is false.
190  // - If both are false, then the variable (and the literal) is unassigned.
191  Bitset64<LiteralIndex> assignment_;
192 
193  DISALLOW_COPY_AND_ASSIGN(VariablesAssignment);
194 };
195 
196 // Forward declaration.
197 class SatClause;
198 class SatPropagator;
199 
200 // Information about a variable assignment.
202  // The decision level at which this assignment was made. This starts at 0 and
203  // increases each time the solver takes a search decision.
204  //
205  // TODO(user): We may be able to get rid of that for faster enqueues. Most of
206  // the code only need to know if this is 0 or the highest level, and for the
207  // LBD computation, the literal of the conflict are already ordered by level,
208  // so we could do it fairly efficiently.
209  //
210  // TODO(user): We currently don't support more than 2^28 decision levels. That
211  // should be enough for most practical problem, but we should fail properly if
212  // this limit is reached.
213  uint32_t level : 28;
214 
215  // The type of assignment (see AssignmentType below).
216  //
217  // Note(user): We currently don't support more than 16 types of assignment.
218  // This is checked in RegisterPropagator().
219  mutable uint32_t type : 4;
220 
221  // The index of this assignment in the trail.
222  int32_t trail_index;
223 
224  std::string DebugString() const {
225  return absl::StrFormat("level:%d type:%d trail_index:%d", level, type,
226  trail_index);
227  }
228 };
229 static_assert(sizeof(AssignmentInfo) == 8,
230  "ERROR_AssignmentInfo_is_not_well_compacted");
231 
232 // Each literal on the trail will have an associated propagation "type" which is
233 // either one of these special types or the id of a propagator.
235  static constexpr int kCachedReason = 0;
236  static constexpr int kUnitReason = 1;
237  static constexpr int kSearchDecision = 2;
238  static constexpr int kSameReasonAs = 3;
239 
240  // Propagator ids starts from there and are created dynamically.
241  static constexpr int kFirstFreePropagationId = 4;
242 };
243 
244 // The solver trail stores the assignment made by the solver in order.
245 // This class is responsible for maintaining the assignment of each variable
246 // and the information of each assignment.
247 class Trail {
248  public:
249  Trail() {
250  current_info_.trail_index = 0;
251  current_info_.level = 0;
252  }
253 
254  void Resize(int num_variables);
255 
256  // Registers a propagator. This assigns a unique id to this propagator and
257  // calls SetPropagatorId() on it.
258  void RegisterPropagator(SatPropagator* propagator);
259 
260  // Enqueues the assignment that make the given literal true on the trail. This
261  // should only be called on unassigned variables.
262  void Enqueue(Literal true_literal, int propagator_id) {
263  DCHECK(!assignment_.VariableIsAssigned(true_literal.Variable()));
264  trail_[current_info_.trail_index] = true_literal;
265  current_info_.type = propagator_id;
266  info_[true_literal.Variable()] = current_info_;
267  assignment_.AssignFromTrueLiteral(true_literal);
268  ++current_info_.trail_index;
269  }
270 
271  // Specific Enqueue() version for the search decision.
272  void EnqueueSearchDecision(Literal true_literal) {
274  }
275 
276  // Specific Enqueue() version for a fixed variable.
277  void EnqueueWithUnitReason(Literal true_literal) {
278  Enqueue(true_literal, AssignmentType::kUnitReason);
279  }
280 
281  // Some constraints propagate a lot of literals at once. In these cases, it is
282  // more efficient to have all the propagated literals except the first one
283  // referring to the reason of the first of them.
284  void EnqueueWithSameReasonAs(Literal true_literal,
285  BooleanVariable reference_var) {
286  reference_var_with_same_reason_as_[true_literal.Variable()] = reference_var;
287  Enqueue(true_literal, AssignmentType::kSameReasonAs);
288  }
289 
290  // Enqueues the given literal using the current content of
291  // GetEmptyVectorToStoreReason() as the reason. This API is a bit more
292  // leanient and does not require the literal to be unassigned. If it is
293  // already assigned to false, then MutableConflict() will be set appropriately
294  // and this will return false otherwise this will enqueue the literal and
295  // returns true.
296  ABSL_MUST_USE_RESULT bool EnqueueWithStoredReason(Literal true_literal) {
297  if (assignment_.LiteralIsTrue(true_literal)) return true;
298  if (assignment_.LiteralIsFalse(true_literal)) {
299  *MutableConflict() = reasons_repository_[Index()];
300  MutableConflict()->push_back(true_literal);
301  return false;
302  }
303 
304  Enqueue(true_literal, AssignmentType::kCachedReason);
305  const BooleanVariable var = true_literal.Variable();
306  reasons_[var] = reasons_repository_[info_[var].trail_index];
307  old_type_[var] = info_[var].type;
308  info_[var].type = AssignmentType::kCachedReason;
309  return true;
310  }
311 
312  // Returns the reason why this variable was assigned.
313  //
314  // Note that this shouldn't be called on a variable at level zero, because we
315  // don't cleanup the reason data for these variables but the underlying
316  // clauses may have been deleted.
317  absl::Span<const Literal> Reason(BooleanVariable var) const;
318 
319  // Returns the "type" of an assignment (see AssignmentType). Note that this
320  // function never returns kSameReasonAs or kCachedReason, it instead returns
321  // the initial type that caused this assignment. As such, it is different
322  // from Info(var).type and the latter should not be used outside this class.
323  int AssignmentType(BooleanVariable var) const;
324 
325  // If a variable was propagated with EnqueueWithSameReasonAs(), returns its
326  // reference variable. Otherwise return the given variable.
327  BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const;
328 
329  // This can be used to get a location at which the reason for the literal
330  // at trail_index on the trail can be stored. This clears the vector before
331  // returning it.
332  std::vector<Literal>* GetEmptyVectorToStoreReason(int trail_index) const {
333  if (trail_index >= reasons_repository_.size()) {
334  reasons_repository_.resize(trail_index + 1);
335  }
336  reasons_repository_[trail_index].clear();
337  return &reasons_repository_[trail_index];
338  }
339 
340  // Shortcut for GetEmptyVectorToStoreReason(Index()).
341  std::vector<Literal>* GetEmptyVectorToStoreReason() const {
343  }
344 
345  // Explicitly overwrite the reason so that the given propagator will be
346  // asked for it. This is currently only used by the BinaryImplicationGraph.
347  void ChangeReason(int trail_index, int propagator_id) {
348  const BooleanVariable var = trail_[trail_index].Variable();
349  info_[var].type = propagator_id;
350  old_type_[var] = propagator_id;
351  }
352 
353  // Reverts the trail and underlying assignment to the given target trail
354  // index. Note that we do not touch the assignment info.
355  void Untrail(int target_trail_index) {
356  const int index = Index();
357  num_untrailed_enqueues_ += index - target_trail_index;
358  for (int i = target_trail_index; i < index; ++i) {
359  assignment_.UnassignLiteral(trail_[i]);
360  }
361  current_info_.trail_index = target_trail_index;
362  }
363  void Dequeue() { Untrail(Index() - 1); }
364 
365  // Changes the decision level used by the next Enqueue().
366  void SetDecisionLevel(int level) { current_info_.level = level; }
367  int CurrentDecisionLevel() const { return current_info_.level; }
368 
369  // Generic interface to set the current failing clause.
370  //
371  // Returns the address of a vector where a client can store the current
372  // conflict. This vector will be returned by the FailingClause() call.
373  std::vector<Literal>* MutableConflict() {
374  failing_sat_clause_ = nullptr;
375  return &conflict_;
376  }
377 
378  // Returns the last conflict.
379  absl::Span<const Literal> FailingClause() const {
380  if (DEBUG_MODE && debug_checker_ != nullptr) {
381  debug_checker_(conflict_);
382  }
383  return conflict_;
384  }
385 
386  // Specific SatClause interface so we can update the conflict clause activity.
387  // Note that MutableConflict() automatically sets this to nullptr, so we can
388  // know whether or not the last conflict was caused by a clause.
389  void SetFailingSatClause(SatClause* clause) { failing_sat_clause_ = clause; }
390  SatClause* FailingSatClause() const { return failing_sat_clause_; }
391 
392  // Getters.
393  int NumVariables() const { return trail_.size(); }
394  int64_t NumberOfEnqueues() const { return num_untrailed_enqueues_ + Index(); }
395  int Index() const { return current_info_.trail_index; }
396  // This accessor can return trail_.end(). operator[] cannot. This allows
397  // normal std:vector operations, such as assign(begin, end).
398  const std::vector<Literal>::const_iterator IteratorAt(int index) const {
399  return trail_.begin() + index;
400  }
401  const Literal& operator[](int index) const { return trail_[index]; }
402  const VariablesAssignment& Assignment() const { return assignment_; }
403  const AssignmentInfo& Info(BooleanVariable var) const {
404  DCHECK_GE(var, 0);
405  DCHECK_LT(var, info_.size());
406  return info_[var];
407  }
408 
409  // Print the current literals on the trail.
410  std::string DebugString() {
411  std::string result;
412  for (int i = 0; i < current_info_.trail_index; ++i) {
413  if (!result.empty()) result += " ";
414  result += trail_[i].DebugString();
415  }
416  return result;
417  }
418 
420  std::function<bool(absl::Span<const Literal> clause)> checker) {
421  debug_checker_ = std::move(checker);
422  }
423 
424  private:
425  int64_t num_untrailed_enqueues_ = 0;
426  AssignmentInfo current_info_;
427  VariablesAssignment assignment_;
428  std::vector<Literal> trail_;
429  std::vector<Literal> conflict_;
431  SatClause* failing_sat_clause_;
432 
433  // Data used by EnqueueWithSameReasonAs().
435  reference_var_with_same_reason_as_;
436 
437  // Reason cache. Mutable since we want the API to be the same whether the
438  // reason are cached or not.
439  //
440  // When a reason is computed for the first time, we change the type of the
441  // variable assignment to kCachedReason so that we know that if it is needed
442  // again the reason can just be retrieved by a direct access to reasons_. The
443  // old type is saved in old_type_ and can be retrieved by
444  // AssignmentType().
445  //
446  // Note(user): Changing the type is not "clean" but it is efficient. The idea
447  // is that it is important to do as little as possible when pushing/popping
448  // literals on the trail. Computing the reason happens a lot less often, so it
449  // is okay to do slightly more work then. Note also, that we don't need to
450  // do anything on "untrail", the kCachedReason type will be overwritten when
451  // the same variable is assigned again.
452  //
453  // TODO(user): An alternative would be to change the sign of the type. This
454  // would remove the need for a separate old_type_ vector, but it requires
455  // more bits for the type filed in AssignmentInfo.
456  //
457  // Note that we use a deque for the reason repository so that if we add
458  // variables, the memory address of the vectors (kept in reasons_) are still
459  // valid.
460  mutable std::deque<std::vector<Literal>> reasons_repository_;
462  reasons_;
464 
465  // This is used by RegisterPropagator() and Reason().
466  std::vector<SatPropagator*> propagators_;
467 
468  std::function<bool(absl::Span<const Literal> clause)> debug_checker_ =
469  nullptr;
470 
471  DISALLOW_COPY_AND_ASSIGN(Trail);
472 };
473 
474 // Base class for all the SAT constraints.
476  public:
477  explicit SatPropagator(const std::string& name)
479  virtual ~SatPropagator() {}
480 
481  // Sets/Gets this propagator unique id.
482  void SetPropagatorId(int id) { propagator_id_ = id; }
483  int PropagatorId() const { return propagator_id_; }
484 
485  // Inspects the trail from propagation_trail_index_ until at least one literal
486  // is propagated. Returns false iff a conflict is detected (in which case
487  // trail->SetFailingClause() must be called).
488  //
489  // This must update propagation_trail_index_ so that all the literals before
490  // it have been propagated. In particular, if nothing was propagated, then
491  // PropagationIsDone() must return true.
492  virtual bool Propagate(Trail* trail) = 0;
493 
494  // Reverts the state so that all the literals with a trail index greater or
495  // equal to the given one are not processed for propagation. Note that the
496  // trail current decision level is already reverted before this is called.
497  //
498  // TODO(user): Currently this is called at each Backtrack(), but we could
499  // bundle the calls in case multiple conflict one after the other are detected
500  // even before the Propagate() call of a SatPropagator is called.
501  //
502  // TODO(user): It is not yet 100% the case, but this can be guaranteed to be
503  // called with a trail index that will always be the start of a new decision
504  // level.
505  virtual void Untrail(const Trail& trail, int trail_index) {
507  }
508 
509  // Explains why the literal at given trail_index was propagated by returning a
510  // reason for this propagation. This will only be called for literals that are
511  // on the trail and were propagated by this class.
512  //
513  // The interpretation is that because all the literals of a reason were
514  // assigned to false, we could deduce the assignment of the given variable.
515  //
516  // The returned Span has to be valid until the literal is untrailed. A client
517  // can use trail_.GetEmptyVectorToStoreReason() if it doesn't have a memory
518  // location that already contains the reason.
519  virtual absl::Span<const Literal> Reason(const Trail& trail,
520  int trail_index) const {
521  LOG(FATAL) << "Not implemented.";
522  return {};
523  }
524 
525  // Returns true if all the preconditions for Propagate() are satisfied.
526  // This is just meant to be used in a DCHECK.
527  bool PropagatePreconditionsAreSatisfied(const Trail& trail) const;
528 
529  // Returns true iff all the trail was inspected by this propagator.
530  bool PropagationIsDone(const Trail& trail) const {
531  return propagation_trail_index_ == trail.Index();
532  }
533 
534  // Small optimization: If a propagator does not contain any "constraints"
535  // there is no point calling propagate on it. Before each propagation, the
536  // solver will checks for emptiness, and construct an optimized list of
537  // propagator before looping many time over the list.
538  virtual bool IsEmpty() const { return false; }
539 
540  protected:
541  const std::string name_;
544 
545  private:
546  DISALLOW_COPY_AND_ASSIGN(SatPropagator);
547 };
548 
549 // ######################## Implementations below ########################
550 
551 // TODO(user): A few of these method should be moved in a .cc
552 
554  const Trail& trail) const {
555  if (propagation_trail_index_ > trail.Index()) {
556  LOG(INFO) << "Issue in '" << name_ << ":"
557  << " propagation_trail_index_=" << propagation_trail_index_
558  << " trail_.Index()=" << trail.Index();
559  return false;
560  }
561  if (propagation_trail_index_ < trail.Index() &&
562  trail.Info(trail[propagation_trail_index_].Variable()).level !=
563  trail.CurrentDecisionLevel()) {
564  LOG(INFO) << "Issue in '" << name_ << "':"
565  << " propagation_trail_index_=" << propagation_trail_index_
566  << " trail_.Index()=" << trail.Index()
567  << " level_at_propagation_index="
568  << trail.Info(trail[propagation_trail_index_].Variable()).level
569  << " current_decision_level=" << trail.CurrentDecisionLevel();
570  return false;
571  }
572  return true;
573 }
574 
575 inline void Trail::Resize(int num_variables) {
576  assignment_.Resize(num_variables);
577  info_.resize(num_variables);
578  trail_.resize(num_variables);
579  reasons_.resize(num_variables);
580 
581  // TODO(user): these vectors are not always used. Initialize them
582  // dynamically.
583  old_type_.resize(num_variables);
584  reference_var_with_same_reason_as_.resize(num_variables);
585 }
586 
587 inline void Trail::RegisterPropagator(SatPropagator* propagator) {
588  if (propagators_.empty()) {
589  propagators_.resize(AssignmentType::kFirstFreePropagationId);
590  }
591  CHECK_LT(propagators_.size(), 16);
592  propagator->SetPropagatorId(propagators_.size());
593  propagators_.push_back(propagator);
594 }
595 
596 inline BooleanVariable Trail::ReferenceVarWithSameReason(
597  BooleanVariable var) const {
598  DCHECK(Assignment().VariableIsAssigned(var));
599  // Note that we don't use AssignmentType() here.
600  if (info_[var].type == AssignmentType::kSameReasonAs) {
601  var = reference_var_with_same_reason_as_[var];
602  DCHECK(Assignment().VariableIsAssigned(var));
603  DCHECK_NE(info_[var].type, AssignmentType::kSameReasonAs);
604  }
605  return var;
606 }
607 
608 inline int Trail::AssignmentType(BooleanVariable var) const {
609  if (info_[var].type == AssignmentType::kSameReasonAs) {
610  var = reference_var_with_same_reason_as_[var];
611  DCHECK_NE(info_[var].type, AssignmentType::kSameReasonAs);
612  }
613  const int type = info_[var].type;
614  return type != AssignmentType::kCachedReason ? type : old_type_[var];
615 }
616 
617 inline absl::Span<const Literal> Trail::Reason(BooleanVariable var) const {
618  // Special case for AssignmentType::kSameReasonAs to avoid a recursive call.
620 
621  // Fast-track for cached reason.
622  if (info_[var].type == AssignmentType::kCachedReason) {
623  if (DEBUG_MODE && debug_checker_ != nullptr) {
624  std::vector<Literal> clause;
625  clause.assign(reasons_[var].begin(), reasons_[var].end());
626  clause.push_back(assignment_.GetTrueLiteralForAssignedVariable(var));
627  debug_checker_(clause);
628  }
629  return reasons_[var];
630  }
631 
632  const AssignmentInfo& info = info_[var];
633  if (info.type == AssignmentType::kUnitReason ||
635  reasons_[var] = {};
636  } else {
637  DCHECK_LT(info.type, propagators_.size());
638  DCHECK(propagators_[info.type] != nullptr) << info.type;
639  reasons_[var] = propagators_[info.type]->Reason(*this, info.trail_index);
640  }
641  old_type_[var] = info.type;
642  info_[var].type = AssignmentType::kCachedReason;
643  if (DEBUG_MODE && debug_checker_ != nullptr) {
644  std::vector<Literal> clause;
645  clause.assign(reasons_[var].begin(), reasons_[var].end());
646  clause.push_back(assignment_.GetTrueLiteralForAssignedVariable(var));
647  debug_checker_(clause);
648  }
649  return reasons_[var];
650 }
651 
652 } // namespace sat
653 } // namespace operations_research
654 
655 #endif // OR_TOOLS_SAT_SAT_BASE_H_
int64_t min
Definition: alldiff_cst.cc:139
void resize(size_type new_size)
IndexType size() const
Definition: bitset.h:441
void Set(IndexType i)
Definition: bitset.h:514
void Resize(IndexType size)
Definition: bitset.h:452
bool IsSet(IndexType i) const
Definition: bitset.h:504
void ClearTwoBits(IndexType i)
Definition: bitset.h:490
bool AreOneOfTwoBitsSet(IndexType i) const
Definition: bitset.h:497
Literal(int signed_value)
Definition: sat_base.h:74
LiteralIndex NegatedIndex() const
Definition: sat_base.h:91
LiteralIndex Index() const
Definition: sat_base.h:90
Literal(LiteralIndex index)
Definition: sat_base.h:81
Literal(BooleanVariable variable, bool is_positive)
Definition: sat_base.h:82
BooleanVariable Variable() const
Definition: sat_base.h:86
std::string DebugString() const
Definition: sat_base.h:99
bool operator==(Literal other) const
Definition: sat_base.h:102
bool operator!=(Literal other) const
Definition: sat_base.h:103
bool operator<(const Literal &literal) const
Definition: sat_base.h:105
virtual bool Propagate(Trail *trail)=0
SatPropagator(const std::string &name)
Definition: sat_base.h:477
virtual absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const
Definition: sat_base.h:519
bool PropagatePreconditionsAreSatisfied(const Trail &trail) const
Definition: sat_base.h:553
virtual void Untrail(const Trail &trail, int trail_index)
Definition: sat_base.h:505
bool PropagationIsDone(const Trail &trail) const
Definition: sat_base.h:530
absl::Span< const Literal > FailingClause() const
Definition: sat_base.h:379
void RegisterPropagator(SatPropagator *propagator)
Definition: sat_base.h:587
void Enqueue(Literal true_literal, int propagator_id)
Definition: sat_base.h:262
const Literal & operator[](int index) const
Definition: sat_base.h:401
void ChangeReason(int trail_index, int propagator_id)
Definition: sat_base.h:347
const AssignmentInfo & Info(BooleanVariable var) const
Definition: sat_base.h:403
int64_t NumberOfEnqueues() const
Definition: sat_base.h:394
SatClause * FailingSatClause() const
Definition: sat_base.h:390
void EnqueueWithSameReasonAs(Literal true_literal, BooleanVariable reference_var)
Definition: sat_base.h:284
int AssignmentType(BooleanVariable var) const
Definition: sat_base.h:608
std::vector< Literal > * GetEmptyVectorToStoreReason(int trail_index) const
Definition: sat_base.h:332
std::vector< Literal > * GetEmptyVectorToStoreReason() const
Definition: sat_base.h:341
void SetFailingSatClause(SatClause *clause)
Definition: sat_base.h:389
std::vector< Literal > * MutableConflict()
Definition: sat_base.h:373
absl::Span< const Literal > Reason(BooleanVariable var) const
Definition: sat_base.h:617
BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const
Definition: sat_base.h:596
void RegisterDebugChecker(std::function< bool(absl::Span< const Literal > clause)> checker)
Definition: sat_base.h:419
const VariablesAssignment & Assignment() const
Definition: sat_base.h:402
ABSL_MUST_USE_RESULT bool EnqueueWithStoredReason(Literal true_literal)
Definition: sat_base.h:296
void Untrail(int target_trail_index)
Definition: sat_base.h:355
const std::vector< Literal >::const_iterator IteratorAt(int index) const
Definition: sat_base.h:398
void SetDecisionLevel(int level)
Definition: sat_base.h:366
void Resize(int num_variables)
Definition: sat_base.h:575
void EnqueueWithUnitReason(Literal true_literal)
Definition: sat_base.h:277
void EnqueueSearchDecision(Literal true_literal)
Definition: sat_base.h:272
bool LiteralIsAssigned(Literal literal) const
Definition: sat_base.h:167
bool VariableIsAssigned(BooleanVariable var) const
Definition: sat_base.h:172
bool LiteralIsTrue(Literal literal) const
Definition: sat_base.h:164
void AssignFromTrueLiteral(Literal literal)
Definition: sat_base.h:147
Literal GetTrueLiteralForAssignedVariable(BooleanVariable var) const
Definition: sat_base.h:179
bool LiteralIsFalse(Literal literal) const
Definition: sat_base.h:161
const std::string name
int64_t value
IntVar * var
Definition: expr_array.cc:1874
int index
const bool DEBUG_MODE
Definition: macros.h:24
DEFINE_STRONG_INDEX_TYPE(ClauseIndex)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:88
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.
Literal literal
Definition: optimization.cc:88
std::optional< int64_t > end
static constexpr int kSameReasonAs
Definition: sat_base.h:238
static constexpr int kFirstFreePropagationId
Definition: sat_base.h:241
static constexpr int kSearchDecision
Definition: sat_base.h:237
static constexpr int kCachedReason
Definition: sat_base.h:235