OR-Tools  9.1
presolve_context.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 #ifndef OR_TOOLS_SAT_PRESOLVE_CONTEXT_H_
15 #define OR_TOOLS_SAT_PRESOLVE_CONTEXT_H_
16 
17 #include <cstdint>
18 #include <deque>
19 #include <string>
20 #include <vector>
21 
24 #include "ortools/sat/model.h"
27 #include "ortools/sat/util.h"
29 #include "ortools/util/bitset.h"
30 #include "ortools/util/logging.h"
33 
34 namespace operations_research {
35 namespace sat {
36 
37 // We use some special constraint index in our variable <-> constraint graph.
38 constexpr int kObjectiveConstraint = -1;
39 constexpr int kAffineRelationConstraint = -2;
40 constexpr int kAssumptionsConstraint = -3;
41 
42 class PresolveContext;
43 
44 // When storing a reference to a literal, it is important not to forget when
45 // reading it back to take its representative. Otherwise, we might introduce
46 // literal that have already been removed, which will break invariants in a
47 // bunch of places.
48 class SavedLiteral {
49  public:
51  explicit SavedLiteral(int ref) : ref_(ref) {}
52  int Get(PresolveContext* context) const;
53 
54  private:
55  int ref_ = 0;
56 };
57 
58 // Same as SavedLiteral for variable.
60  public:
62  explicit SavedVariable(int ref) : ref_(ref) {}
63  int Get(PresolveContext* context) const;
64 
65  private:
66  int ref_ = 0;
67 };
68 
69 // Wrap the CpModelProto we are presolving with extra data structure like the
70 // in-memory domain of each variables and the constraint variable graph.
72  public:
73  explicit PresolveContext(Model* model, CpModelProto* cp_model,
74  CpModelProto* mapping)
75  : working_model(cp_model),
76  mapping_model(mapping),
77  logger_(model->GetOrCreate<SolverLogger>()),
78  params_(*model->GetOrCreate<SatParameters>()),
79  time_limit_(model->GetOrCreate<TimeLimit>()),
80  random_(model->GetOrCreate<ModelRandomGenerator>()) {}
81 
82  // Helpers to adds new variables to the presolved model.
83  int NewIntVar(const Domain& domain);
84  int NewBoolVar();
85  int GetOrCreateConstantVar(int64_t cst);
86 
87  // a => b.
88  void AddImplication(int a, int b);
89 
90  // b => x in [lb, ub].
91  void AddImplyInDomain(int b, int x, const Domain& domain);
92 
93  // Helpers to query the current domain of a variable.
94  bool DomainIsEmpty(int ref) const;
95  bool IsFixed(int ref) const;
96  bool CanBeUsedAsLiteral(int ref) const;
97  bool LiteralIsTrue(int lit) const;
98  bool LiteralIsFalse(int lit) const;
99  int64_t MinOf(int ref) const;
100  int64_t MaxOf(int ref) const;
101  bool DomainContains(int ref, int64_t value) const;
102  Domain DomainOf(int ref) const;
103 
104  // Helper to query the state of an interval.
105  bool IntervalIsConstant(int ct_ref) const;
106  int64_t StartMin(int ct_ref) const;
107  int64_t StartMax(int ct_ref) const;
108  int64_t SizeMin(int ct_ref) const;
109  int64_t SizeMax(int ct_ref) const;
110  int64_t EndMin(int ct_ref) const;
111  int64_t EndMax(int ct_ref) const;
112  std::string IntervalDebugString(int ct_ref) const;
113 
114  // Helpers to query the current domain of a linear expression.
115  // This doesn't check for integer overflow, but our linear expression
116  // should be such that this cannot happen (tested at validation).
117  int64_t MinOf(const LinearExpressionProto& expr) const;
118  int64_t MaxOf(const LinearExpressionProto& expr) const;
119 
120  // Return a super-set of the domain of the linear expression.
121  Domain DomainSuperSetOf(const LinearExpressionProto& expr) const;
122 
123  // Returns true iff the expr is of the for a * literal + b.
124  // The other function can be used to get the liteal that achieve MaxOf().
125  bool ExpressionIsAffineBoolean(const LinearExpressionProto& expr) const;
126  int LiteralForExpressionMax(const LinearExpressionProto& expr) const;
127 
128  // This function takes a positive variable reference.
129  bool DomainOfVarIsIncludedIn(int var, const Domain& domain) {
130  return domains[var].IsIncludedIn(domain);
131  }
132 
133  // Returns true if a presolve transformation is allowed to remove this
134  // variable.
135  bool VariableIsRemovable(int ref) const;
136 
137  // Returns true if this ref only appear in one constraint.
138  bool VariableIsUniqueAndRemovable(int ref) const;
139 
140  // Returns true if this ref no longer appears in the model.
141  bool VariableIsNotUsedAnymore(int ref) const;
142 
143  // Functions to make sure that once we remove a variable, we no longer reuse
144  // it.
145  void MarkVariableAsRemoved(int ref);
146  bool VariableWasRemoved(int ref) const;
147 
148  // Same as VariableIsUniqueAndRemovable() except that in this case the
149  // variable also appear in the objective in addition to a single constraint.
150  bool VariableWithCostIsUniqueAndRemovable(int ref) const;
151 
152  // Returns true if an integer variable is only appearing in the rhs of
153  // constraints of the form lit => var in domain. When this is the case, then
154  // we can usually remove this variable and replace these constraints with
155  // the proper constraints on the enforcement literals.
157 
158  // Returns false if the new domain is empty. Sets 'domain_modified' (if
159  // provided) to true iff the domain is modified otherwise does not change it.
160  ABSL_MUST_USE_RESULT bool IntersectDomainWith(
161  int ref, const Domain& domain, bool* domain_modified = nullptr);
162 
163  // Returns false if the 'lit' doesn't have the desired value in the domain.
164  ABSL_MUST_USE_RESULT bool SetLiteralToFalse(int lit);
165  ABSL_MUST_USE_RESULT bool SetLiteralToTrue(int lit);
166 
167  // Same as IntersectDomainWith() but take a linear expression as input.
168  // If this expression if of size > 1, this does nothing for now, so it will
169  // only propagates for constant and affine expression.
170  ABSL_MUST_USE_RESULT bool IntersectDomainWith(
171  const LinearExpressionProto& expr, const Domain& domain,
172  bool* domain_modified = nullptr);
173 
174  // This function always return false. It is just a way to make a little bit
175  // more sure that we abort right away when infeasibility is detected.
176  ABSL_MUST_USE_RESULT bool NotifyThatModelIsUnsat(
177  const std::string& message = "") {
178  // TODO(user): Report any explanation for the client in a nicer way?
179  VLOG(1) << "INFEASIBLE: '" << message << "'";
180  DCHECK(!is_unsat_);
181  is_unsat_ = true;
182  return false;
183  }
184  bool ModelIsUnsat() const { return is_unsat_; }
185 
186  // Stores a description of a rule that was just applied to have a summary of
187  // what the presolve did at the end.
188  void UpdateRuleStats(const std::string& name, int num_times = 1);
189 
190  // Updates the constraints <-> variables graph. This needs to be called each
191  // time a constraint is modified.
192  void UpdateConstraintVariableUsage(int c);
193 
194  // At the beginning of the presolve, we delay the costly creation of this
195  // "graph" until we at least ran some basic presolve. This is because during
196  // a LNS neighbhorhood, many constraints will be reduced significantly by
197  // this "simple" presolve.
199 
200  // Calls UpdateConstraintVariableUsage() on all newly created constraints.
202 
203  // Returns true if our current constraints <-> variables graph is ok.
204  // This is meant to be used in DEBUG mode only.
206 
207  // Regroups fixed variables with the same value.
208  // TODO(user): Also regroup cte and -cte?
209  void ExploitFixedDomain(int var);
210 
211  // Adds the relation (ref_x = coeff * ref_y + offset) to the repository.
212  // Once the relation is added, it doesn't need to be enforced by a constraint
213  // in the model proto, since we will propagate such relation directly and add
214  // them to the proto at the end of the presolve.
215  //
216  // Returns true if the relation was added.
217  // In some rare case, like if x = 3*z and y = 5*t are already added, we
218  // currently cannot add x = 2 * y and we will return false in these case. So
219  // when this returns false, the relation needs to be enforced by a separate
220  // constraint.
221  //
222  // If the relation was added, both variables will be marked to appear in the
223  // special kAffineRelationConstraint. This will allow to identify when a
224  // variable is no longer needed (only appear there and is not a
225  // representative).
226  bool StoreAffineRelation(int ref_x, int ref_y, int64_t coeff, int64_t offset);
227 
228  // Adds the fact that ref_a == ref_b using StoreAffineRelation() above.
229  // This should never fail, so the relation will always be added.
230  void StoreBooleanEqualityRelation(int ref_a, int ref_b);
231 
232  // Stores/Get the relation target_ref = abs(ref); The first function returns
233  // false if it already exist and the second false if it is not present.
234  bool StoreAbsRelation(int target_ref, int ref);
235  bool GetAbsRelation(int target_ref, int* ref);
236 
237  // Returns the representative of a literal.
238  int GetLiteralRepresentative(int ref) const;
239 
240  // Returns another reference with exactly the same value.
241  int GetVariableRepresentative(int ref) const;
242 
243  // Used for statistics.
244  int NumAffineRelations() const { return affine_relations_.NumRelations(); }
245  int NumEquivRelations() const { return var_equiv_relations_.NumRelations(); }
246 
247  // This makes sure that the affine relation only uses one of the
248  // representative from the var_equiv_relations.
250 
251  // To facilitate debugging.
252  std::string RefDebugString(int ref) const;
253  std::string AffineRelationDebugString(int ref) const;
254 
255  // Makes sure the domain of ref and of its representative are in sync.
256  // Returns false on unsat.
257  bool PropagateAffineRelation(int ref);
258 
259  // Creates the internal structure for any new variables in working_model.
260  void InitializeNewDomains();
261 
262  // Clears the "rules" statistics.
263  void ClearStats();
264 
265  // Inserts the given literal to encode ref == value.
266  // If an encoding already exists, it adds the two implications between
267  // the previous encoding and the new encoding.
268  //
269  // Important: This does not update the constraint<->variable graph, so
270  // ConstraintVariableGraphIsUpToDate() will be false until
271  // UpdateNewConstraintsVariableUsage() is called.
272  void InsertVarValueEncoding(int literal, int ref, int64_t value);
273 
274  // Gets the associated literal if it is already created. Otherwise
275  // create it, add the corresponding constraints and returns it.
276  //
277  // Important: This does not update the constraint<->variable graph, so
278  // ConstraintVariableGraphIsUpToDate() will be false until
279  // UpdateNewConstraintsVariableUsage() is called.
280  int GetOrCreateVarValueEncoding(int ref, int64_t value);
281 
282  // If not already done, adds a Boolean to represent any integer variables that
283  // take only two values. Make sure all the relevant affine and encoding
284  // relations are updated.
285  //
286  // Note that this might create a new Boolean variable.
288 
289  // Returns true if a literal attached to ref == var exists.
290  // It assigns the corresponding to `literal` if non null.
291  bool HasVarValueEncoding(int ref, int64_t value, int* literal = nullptr);
292 
293  // Stores the fact that literal implies var == value.
294  // It returns true if that information is new.
295  bool StoreLiteralImpliesVarEqValue(int literal, int var, int64_t value);
296 
297  // Stores the fact that literal implies var != value.
298  // It returns true if that information is new.
299  bool StoreLiteralImpliesVarNEqValue(int literal, int var, int64_t value);
300 
301  // Objective handling functions. We load it at the beginning so that during
302  // presolve we can work on the more efficient hash_map representation.
303  //
304  // Note that ReadObjectiveFromProto() makes sure that var_to_constraints of
305  // all the variable that appear in the objective contains -1. This is later
306  // enforced by all the functions modifying the objective.
307  //
308  // Note(user): Because we process affine relation only on
309  // CanonicalizeObjective(), it is possible that when processing a
310  // canonicalized linear constraint, we don't detect that a variable in affine
311  // relation is in the objective. For now this is fine, because when this is
312  // the case, we also have an affine linear constraint, so we can't really do
313  // anything with that variable since it appear in at least two constraints.
314  void ReadObjectiveFromProto();
315  ABSL_MUST_USE_RESULT bool CanonicalizeObjective();
316  void WriteObjectiveToProto() const;
317 
318  // Checks if the given exactly_one is included in the objective, and simplify
319  // the objective by adding a constant value to all the exactly one terms.
320  bool ExploitExactlyOneInObjective(absl::Span<const int> exactly_one);
321 
322  // Allows to manipulate the objective coefficients.
324  void AddToObjective(int var, int64_t value);
325  void AddToObjectiveOffset(int64_t value);
326 
327  // Given a variable defined by the given inequality that also appear in the
328  // objective, remove it from the objective by transferring its cost to other
329  // variables in the equality.
330  //
331  // If new_vars_in_objective is not nullptr, it will be filled with "new"
332  // variables that where not in the objective before and are after
333  // substitution.
334  //
335  // Returns false, if the substitution cannot be done. This is the case if the
336  // model become UNSAT or if doing it will result in an objective that do not
337  // satisfy our overflow preconditions. Note that this can only happen if the
338  // substitued variable is not implied free (i.e. if its domain is smaller than
339  // the implied domain from the equality).
341  int var_in_equality, int64_t coeff_in_equality,
342  const ConstraintProto& equality,
343  std::vector<int>* new_vars_in_objective = nullptr);
344 
345  // Objective getters.
346  const Domain& ObjectiveDomain() const { return objective_domain_; }
347  const absl::flat_hash_map<int, int64_t>& ObjectiveMap() const {
348  return objective_map_;
349  }
351  return objective_domain_is_constraining_;
352  }
353 
354  // Advanced usage. This should be called when a variable can be removed from
355  // the problem, so we don't count it as part of an affine relation anymore.
358 
359  // Variable <-> constraint graph.
360  // The vector list is sorted and contains unique elements.
361  //
362  // Important: To properly handle the objective, var_to_constraints[objective]
363  // contains -1 so that if the objective appear in only one constraint, the
364  // constraint cannot be simplified.
365  const std::vector<int>& ConstraintToVars(int c) const {
367  return constraint_to_vars_[c];
368  }
369  const absl::flat_hash_set<int>& VarToConstraints(int var) const {
371  return var_to_constraints_[var];
372  }
373  int IntervalUsage(int c) const {
375  return interval_usage_[c];
376  }
377 
378  // Checks if a constraint contains an enforcement literal set to false,
379  // or if it has been cleared.
380  bool ConstraintIsInactive(int ct_index) const;
381 
382  // Checks if a constraint contains an enforcement literal not fixed, and
383  // no enforcement literals set to false.
384  bool ConstraintIsOptional(int ct_ref) const;
385 
386  // Make sure we never delete an "assumption" literal by using a special
387  // constraint for that.
389  for (const int ref : working_model->assumptions()) {
390  var_to_constraints_[PositiveRef(ref)].insert(kAssumptionsConstraint);
391  }
392  }
393 
394  // The "expansion" phase should be done once and allow to transform complex
395  // constraints into basic ones (see cp_model_expand.h). Some presolve rules
396  // need to know if the expansion was ran before beeing applied.
397  bool ModelIsExpanded() const { return model_is_expanded_; }
398  void NotifyThatModelIsExpanded() { model_is_expanded_ = true; }
399 
400  // The following helper adds the following constraint:
401  // result <=> (time_i <= time_j && active_i is true && active_j is true)
402  // and returns the (cached) literal result.
403  //
404  // Note that this cache should just be used temporarily and then cleared
405  // with ClearPrecedenceCache() because there is no mechanism to update the
406  // cached literals when literal equivalence are detected.
407  int GetOrCreateReifiedPrecedenceLiteral(int time_i, int time_j, int active_i,
408  int active_j);
409 
410  // Clear the precedence cache.
411  void ClearPrecedenceCache();
412 
413  // Logs stats to the logger.
414  void LogInfo();
415 
416  SolverLogger* logger() const { return logger_; }
417  const SatParameters& params() const { return params_; }
418  TimeLimit* time_limit() { return time_limit_; }
419  ModelRandomGenerator* random() { return random_; }
420 
421  // For each variables, list the constraints that just enforce a lower bound
422  // (resp. upper bound) on that variable. If all the constraints in which a
423  // variable appear are in the same direction, then we can usually fix a
424  // variable to one of its bound (modulo its cost).
425  //
426  // TODO(user): Keeping these extra vector of hash_set seems inefficient. Come
427  // up with a better way to detect if a variable is only constrainted in one
428  // direction.
429  std::vector<absl::flat_hash_set<int>> var_to_ub_only_constraints;
430  std::vector<absl::flat_hash_set<int>> var_to_lb_only_constraints;
431 
434 
435  // Indicate if we are allowed to remove irrelevant feasible solution from the
436  // set of feasible solution. For example, if a variable is unused, can we fix
437  // it to an arbitrary value (or its mimimum objective one)? This must be true
438  // if the client wants to enumerate all solutions or wants correct tightened
439  // bounds in the response.
441 
442  // Number of "rules" applied. This should be equal to the sum of all numbers
443  // in stats_by_rule_name. This is used to decide if we should do one more pass
444  // of the presolve or not. Note that depending on the presolve transformation,
445  // a rule can correspond to a tiny change or a big change. Because of that,
446  // this isn't a perfect proxy for the efficacy of the presolve.
448 
449  // Temporary storage.
450  std::vector<int> tmp_literals;
451  std::vector<Domain> tmp_term_domains;
452  std::vector<Domain> tmp_left_domains;
453  absl::flat_hash_set<int> tmp_literal_set;
454 
455  // Each time a domain is modified this is set to true.
457 
458  // Advanced presolve. See this class comment.
460 
461  private:
462  // Helper to add an affine relation x = c.y + o to the given repository.
463  bool AddRelation(int x, int y, int64_t c, int64_t o, AffineRelation* repo);
464 
465  void AddVariableUsage(int c);
466  void UpdateLinear1Usage(const ConstraintProto& ct, int c);
467 
468  // Returns true iff the variable is not the representative of an equivalence
469  // class of size at least 2.
470  bool VariableIsNotRepresentativeOfEquivalenceClass(int var) const;
471 
472  // Process encoding_remap_queue_ and updates the encoding maps. This could
473  // lead to UNSAT being detected, in which case it will return false.
474  bool RemapEncodingMaps();
475 
476  // Makes sure we only insert encoding about the current representative.
477  //
478  // Returns false if ref cannot take the given value (it might not have been
479  // propagated yed).
480  bool CanonicalizeEncoding(int* ref, int64_t* value);
481 
482  // Inserts an half reified var value encoding (literal => var ==/!= value).
483  // It returns true if the new state is different from the old state.
484  // Not that if imply_eq is false, the literal will be stored in its negated
485  // form.
486  //
487  // Thus, if you detect literal <=> var == value, then two calls must be made:
488  // InsertHalfVarValueEncoding(literal, var, value, true);
489  // InsertHalfVarValueEncoding(NegatedRef(literal), var, value, false);
490  bool InsertHalfVarValueEncoding(int literal, int var, int64_t value,
491  bool imply_eq);
492 
493  // Insert fully reified var-value encoding.
494  void InsertVarValueEncodingInternal(int literal, int var, int64_t value,
495  bool add_constraints);
496 
497  SolverLogger* logger_;
498  const SatParameters& params_;
499  TimeLimit* time_limit_;
500  ModelRandomGenerator* random_;
501 
502  // Initially false, and set to true on the first inconsistency.
503  bool is_unsat_ = false;
504 
505  // The current domain of each variables.
506  std::vector<Domain> domains;
507 
508  // Internal representation of the objective. During presolve, we first load
509  // the objective in this format in order to have more efficient substitution
510  // on large problems (also because the objective is often dense). At the end
511  // we re-convert it to its proto form.
512  absl::flat_hash_map<int, int64_t> objective_map_;
513  int64_t objective_overflow_detection_;
514  std::vector<std::pair<int, int64_t>> tmp_entries_;
515  bool objective_domain_is_constraining_ = false;
516  Domain objective_domain_;
517  double objective_offset_;
518  double objective_scaling_factor_;
519 
520  // Constraints <-> Variables graph.
521  std::vector<std::vector<int>> constraint_to_vars_;
522  std::vector<absl::flat_hash_set<int>> var_to_constraints_;
523 
524  // Number of constraints of the form [lit =>] var in domain.
525  std::vector<int> constraint_to_linear1_var_;
526  std::vector<int> var_to_num_linear1_;
527 
528  // We maintain how many time each interval is used.
529  std::vector<std::vector<int>> constraint_to_intervals_;
530  std::vector<int> interval_usage_;
531 
532  // Contains abs relation (key = abs(saved_variable)).
533  absl::flat_hash_map<int, SavedVariable> abs_relations_;
534 
535  // For each constant variable appearing in the model, we maintain a reference
536  // variable with the same constant value. If two variables end up having the
537  // same fixed value, then we can detect it using this and add a new
538  // equivalence relation. See ExploitFixedDomain().
539  absl::flat_hash_map<int64_t, SavedVariable> constant_to_ref_;
540 
541  // When a "representative" gets a new representative, it should be enqueued
542  // here so that we can lazily update the *encoding_ maps below.
543  std::deque<int> encoding_remap_queue_;
544 
545  // Contains variables with some encoded value: encoding_[i][v] points
546  // to the literal attached to the value v of the variable i.
547  absl::flat_hash_map<int, absl::flat_hash_map<int64_t, SavedLiteral>>
548  encoding_;
549 
550  // Contains the currently collected half value encodings:
551  // i.e.: literal => var ==/!= value
552  // The state is accumulated (adding x => var == value then !x => var != value)
553  // will deduce that x equivalent to var == value.
554  absl::flat_hash_map<int,
555  absl::flat_hash_map<int64_t, absl::flat_hash_set<int>>>
556  eq_half_encoding_;
557  absl::flat_hash_map<int,
558  absl::flat_hash_map<int64_t, absl::flat_hash_set<int>>>
559  neq_half_encoding_;
560 
561  // This regroups all the affine relations between variables. Note that the
562  // constraints used to detect such relations will not be removed from the
563  // model at detection time (thus allowing proper domain propagation). However,
564  // if the arity of a variable becomes one, then such constraint will be
565  // removed.
566  AffineRelation affine_relations_;
567  AffineRelation var_equiv_relations_;
568 
569  std::vector<int> tmp_new_usage_;
570 
571  // Used by SetVariableAsRemoved() and VariableWasRemoved().
572  absl::flat_hash_set<int> removed_variables_;
573 
574  // Cache for the reified precedence literals created during the expansion of
575  // the reservoir constraint. This cache is only valid during the expansion
576  // phase, and is cleared afterwards.
577  absl::flat_hash_map<std::tuple<int, int, int, int>, int>
578  reified_precedences_cache_;
579 
580  // Just used to display statistics on the presolve rules that were used.
581  absl::flat_hash_map<std::string, int> stats_by_rule_name_;
582 
583  bool model_is_expanded_ = false;
584 };
585 
586 } // namespace sat
587 } // namespace operations_research
588 
589 #endif // OR_TOOLS_SAT_PRESOLVE_CONTEXT_H_
int Get(PresolveContext *context) const
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
void UpdateRuleStats(const std::string &name, int num_times=1)
void StoreBooleanEqualityRelation(int ref_a, int ref_b)
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
void AddToObjective(int var, int64_t value)
bool StoreLiteralImpliesVarNEqValue(int literal, int var, int64_t value)
const absl::flat_hash_set< int > & VarToConstraints(int var) const
constexpr int kAssumptionsConstraint
#define VLOG(verboselevel)
Definition: base/logging.h:979
bool GetAbsRelation(int target_ref, int *ref)
const std::string name
bool StoreAffineRelation(int ref_x, int ref_y, int64_t coeff, int64_t offset)
constexpr int kAffineRelationConstraint
std::string AffineRelationDebugString(int ref) const
GRBmodel * model
bool StoreAbsRelation(int target_ref, int ref)
int LiteralForExpressionMax(const LinearExpressionProto &expr) const
const std::vector< int > & ConstraintToVars(int c) const
bool ExpressionIsAffineBoolean(const LinearExpressionProto &expr) const
bool VariableIsOnlyUsedInEncodingAndMaybeInObjective(int ref) const
int64_t b
ABSL_MUST_USE_RESULT bool SetLiteralToFalse(int lit)
const SatParameters & params() const
bool HasVarValueEncoding(int ref, int64_t value, int *literal=nullptr)
::PROTOBUF_NAMESPACE_ID::int32 assumptions(int index) const
std::vector< absl::flat_hash_set< int > > var_to_ub_only_constraints
ABSL_MUST_USE_RESULT bool IntersectDomainWith(int ref, const Domain &domain, bool *domain_modified=nullptr)
std::string message
Definition: trace.cc:398
absl::flat_hash_set< int > tmp_literal_set
bool VariableWithCostIsUniqueAndRemovable(int ref) const
ABSL_MUST_USE_RESULT bool NotifyThatModelIsUnsat(const std::string &message="")
bool SubstituteVariableInObjective(int var_in_equality, int64_t coeff_in_equality, const ConstraintProto &equality, std::vector< int > *new_vars_in_objective=nullptr)
bool DomainContains(int ref, int64_t value) const
#define DCHECK(condition)
Definition: base/logging.h:885
We call domain any subset of Int64 = [kint64min, kint64max].
int Get(PresolveContext *context) const
Domain DomainSuperSetOf(const LinearExpressionProto &expr) const
std::vector< absl::flat_hash_set< int > > var_to_lb_only_constraints
bool DomainOfVarIsIncludedIn(int var, const Domain &domain)
void AddImplyInDomain(int b, int x, const Domain &domain)
int GetOrCreateReifiedPrecedenceLiteral(int time_i, int time_j, int active_i, int active_j)
bool StoreLiteralImpliesVarEqValue(int literal, int var, int64_t value)
Collection of objects used to extend the Constraint Solver library.
bool ExploitExactlyOneInObjective(absl::Span< const int > exactly_one)
const absl::flat_hash_map< int, int64_t > & ObjectiveMap() const
std::string IntervalDebugString(int ct_ref) const
constexpr int kObjectiveConstraint
IntVar * var
Definition: expr_array.cc:1874
ABSL_MUST_USE_RESULT bool SetLiteralToTrue(int lit)
int GetOrCreateVarValueEncoding(int ref, int64_t value)
GurobiMPCallbackContext * context
void InsertVarValueEncoding(int literal, int ref, int64_t value)
PresolveContext(Model *model, CpModelProto *cp_model, CpModelProto *mapping)
int64_t value
Literal literal
Definition: optimization.cc:85
AffineRelation::Relation GetAffineRelation(int ref) const
const Constraint * ct
ABSL_MUST_USE_RESULT bool CanonicalizeObjective()
int64_t a