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