OR-Tools  9.2
cp_model_utils.cc
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 
15 
16 #include <cstdint>
17 #include <functional>
18 
19 #include "absl/container/flat_hash_map.h"
20 #include "ortools/base/stl_util.h"
22 
23 namespace operations_research {
24 namespace sat {
25 
26 namespace {
27 
28 template <typename IntList>
29 void AddIndices(const IntList& indices, std::vector<int>* output) {
30  output->insert(output->end(), indices.begin(), indices.end());
31 }
32 
33 } // namespace
34 
36  LinearExpressionProto* output_negated_expr) {
37  output_negated_expr->Clear();
38  for (int i = 0; i < input_expr.vars_size(); ++i) {
39  output_negated_expr->add_vars(NegatedRef(input_expr.vars(i)));
40  output_negated_expr->add_coeffs(input_expr.coeffs(i));
41  }
42  output_negated_expr->set_offset(-input_expr.offset());
43 }
44 
46  IndexReferences output;
47  switch (ct.constraint_case()) {
48  case ConstraintProto::ConstraintCase::kBoolOr:
49  AddIndices(ct.bool_or().literals(), &output.literals);
50  break;
51  case ConstraintProto::ConstraintCase::kBoolAnd:
52  AddIndices(ct.bool_and().literals(), &output.literals);
53  break;
54  case ConstraintProto::ConstraintCase::kAtMostOne:
55  AddIndices(ct.at_most_one().literals(), &output.literals);
56  break;
57  case ConstraintProto::ConstraintCase::kExactlyOne:
58  AddIndices(ct.exactly_one().literals(), &output.literals);
59  break;
60  case ConstraintProto::ConstraintCase::kBoolXor:
61  AddIndices(ct.bool_xor().literals(), &output.literals);
62  break;
63  case ConstraintProto::ConstraintCase::kIntDiv:
64  AddIndices(ct.int_div().target().vars(), &output.variables);
65  for (const LinearExpressionProto& expr : ct.int_div().exprs()) {
66  AddIndices(expr.vars(), &output.variables);
67  }
68  break;
69  case ConstraintProto::ConstraintCase::kIntMod:
70  AddIndices(ct.int_mod().target().vars(), &output.variables);
71  for (const LinearExpressionProto& expr : ct.int_mod().exprs()) {
72  AddIndices(expr.vars(), &output.variables);
73  }
74  break;
75  case ConstraintProto::ConstraintCase::kLinMax: {
76  AddIndices(ct.lin_max().target().vars(), &output.variables);
77  for (const LinearExpressionProto& expr : ct.lin_max().exprs()) {
78  AddIndices(expr.vars(), &output.variables);
79  }
80  break;
81  }
82  case ConstraintProto::ConstraintCase::kIntProd:
83  AddIndices(ct.int_prod().target().vars(), &output.variables);
84  for (const LinearExpressionProto& expr : ct.int_prod().exprs()) {
85  AddIndices(expr.vars(), &output.variables);
86  }
87  break;
88  case ConstraintProto::ConstraintCase::kLinear:
89  AddIndices(ct.linear().vars(), &output.variables);
90  break;
91  case ConstraintProto::ConstraintCase::kAllDiff:
92  for (const LinearExpressionProto& expr : ct.all_diff().exprs()) {
93  AddIndices(expr.vars(), &output.variables);
94  }
95  break;
96  case ConstraintProto::ConstraintCase::kDummyConstraint:
97  AddIndices(ct.dummy_constraint().vars(), &output.variables);
98  break;
99  case ConstraintProto::ConstraintCase::kElement:
100  output.variables.push_back(ct.element().index());
101  output.variables.push_back(ct.element().target());
102  AddIndices(ct.element().vars(), &output.variables);
103  break;
104  case ConstraintProto::ConstraintCase::kCircuit:
105  AddIndices(ct.circuit().literals(), &output.literals);
106  break;
107  case ConstraintProto::ConstraintCase::kRoutes:
108  AddIndices(ct.routes().literals(), &output.literals);
109  break;
110  case ConstraintProto::ConstraintCase::kInverse:
111  AddIndices(ct.inverse().f_direct(), &output.variables);
112  AddIndices(ct.inverse().f_inverse(), &output.variables);
113  break;
114  case ConstraintProto::ConstraintCase::kReservoir:
115  for (const LinearExpressionProto& time : ct.reservoir().time_exprs()) {
116  AddIndices(time.vars(), &output.variables);
117  }
118  AddIndices(ct.reservoir().active_literals(), &output.literals);
119  break;
120  case ConstraintProto::ConstraintCase::kTable:
121  AddIndices(ct.table().vars(), &output.variables);
122  break;
123  case ConstraintProto::ConstraintCase::kAutomaton:
124  AddIndices(ct.automaton().vars(), &output.variables);
125  break;
126  case ConstraintProto::ConstraintCase::kInterval:
127  AddIndices(ct.interval().start().vars(), &output.variables);
128  AddIndices(ct.interval().size().vars(), &output.variables);
129  AddIndices(ct.interval().end().vars(), &output.variables);
130  break;
131  case ConstraintProto::ConstraintCase::kNoOverlap:
132  break;
133  case ConstraintProto::ConstraintCase::kNoOverlap2D:
134  break;
135  case ConstraintProto::ConstraintCase::kCumulative:
136  AddIndices(ct.cumulative().capacity().vars(), &output.variables);
137  for (const LinearExpressionProto& demand : ct.cumulative().demands()) {
138  AddIndices(demand.vars(), &output.variables);
139  }
140  break;
141  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
142  break;
143  }
144  return output;
145 }
146 
147 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
148  { \
149  int temp = ct->mutable_##ct_name()->field_name(); \
150  f(&temp); \
151  ct->mutable_##ct_name()->set_##field_name(temp); \
152  }
153 
154 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
155  { \
156  for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
157  }
158 
159 void ApplyToAllLiteralIndices(const std::function<void(int*)>& f,
160  ConstraintProto* ct) {
161  for (int& r : *ct->mutable_enforcement_literal()) f(&r);
162  switch (ct->constraint_case()) {
163  case ConstraintProto::ConstraintCase::kBoolOr:
164  APPLY_TO_REPEATED_FIELD(bool_or, literals);
165  break;
166  case ConstraintProto::ConstraintCase::kBoolAnd:
167  APPLY_TO_REPEATED_FIELD(bool_and, literals);
168  break;
169  case ConstraintProto::ConstraintCase::kAtMostOne:
170  APPLY_TO_REPEATED_FIELD(at_most_one, literals);
171  break;
172  case ConstraintProto::ConstraintCase::kExactlyOne:
173  APPLY_TO_REPEATED_FIELD(exactly_one, literals);
174  break;
175  case ConstraintProto::ConstraintCase::kBoolXor:
176  APPLY_TO_REPEATED_FIELD(bool_xor, literals);
177  break;
178  case ConstraintProto::ConstraintCase::kIntDiv:
179  break;
180  case ConstraintProto::ConstraintCase::kIntMod:
181  break;
182  case ConstraintProto::ConstraintCase::kLinMax:
183  break;
184  case ConstraintProto::ConstraintCase::kIntProd:
185  break;
186  case ConstraintProto::ConstraintCase::kLinear:
187  break;
188  case ConstraintProto::ConstraintCase::kAllDiff:
189  break;
190  case ConstraintProto::ConstraintCase::kDummyConstraint:
191  break;
192  case ConstraintProto::ConstraintCase::kElement:
193  break;
194  case ConstraintProto::ConstraintCase::kCircuit:
195  APPLY_TO_REPEATED_FIELD(circuit, literals);
196  break;
197  case ConstraintProto::ConstraintCase::kRoutes:
198  APPLY_TO_REPEATED_FIELD(routes, literals);
199  break;
200  case ConstraintProto::ConstraintCase::kInverse:
201  break;
202  case ConstraintProto::ConstraintCase::kReservoir:
203  APPLY_TO_REPEATED_FIELD(reservoir, active_literals);
204  break;
205  case ConstraintProto::ConstraintCase::kTable:
206  break;
207  case ConstraintProto::ConstraintCase::kAutomaton:
208  break;
209  case ConstraintProto::ConstraintCase::kInterval:
210  break;
211  case ConstraintProto::ConstraintCase::kNoOverlap:
212  break;
213  case ConstraintProto::ConstraintCase::kNoOverlap2D:
214  break;
215  case ConstraintProto::ConstraintCase::kCumulative:
216  break;
217  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
218  break;
219  }
220 }
221 
222 void ApplyToAllVariableIndices(const std::function<void(int*)>& f,
223  ConstraintProto* ct) {
224  switch (ct->constraint_case()) {
225  case ConstraintProto::ConstraintCase::kBoolOr:
226  break;
227  case ConstraintProto::ConstraintCase::kBoolAnd:
228  break;
229  case ConstraintProto::ConstraintCase::kAtMostOne:
230  break;
231  case ConstraintProto::ConstraintCase::kExactlyOne:
232  break;
233  case ConstraintProto::ConstraintCase::kBoolXor:
234  break;
235  case ConstraintProto::ConstraintCase::kIntDiv:
236  APPLY_TO_REPEATED_FIELD(int_div, target()->mutable_vars);
237  for (int i = 0; i < ct->int_div().exprs_size(); ++i) {
238  APPLY_TO_REPEATED_FIELD(int_div, exprs(i)->mutable_vars);
239  }
240  break;
241  case ConstraintProto::ConstraintCase::kIntMod:
242  APPLY_TO_REPEATED_FIELD(int_mod, target()->mutable_vars);
243  for (int i = 0; i < ct->int_mod().exprs_size(); ++i) {
244  APPLY_TO_REPEATED_FIELD(int_mod, exprs(i)->mutable_vars);
245  }
246  break;
247  case ConstraintProto::ConstraintCase::kLinMax:
248  APPLY_TO_REPEATED_FIELD(lin_max, target()->mutable_vars);
249  for (int i = 0; i < ct->lin_max().exprs_size(); ++i) {
250  APPLY_TO_REPEATED_FIELD(lin_max, exprs(i)->mutable_vars);
251  }
252  break;
253  case ConstraintProto::ConstraintCase::kIntProd:
254  APPLY_TO_REPEATED_FIELD(int_prod, target()->mutable_vars);
255  for (int i = 0; i < ct->int_prod().exprs_size(); ++i) {
256  APPLY_TO_REPEATED_FIELD(int_prod, exprs(i)->mutable_vars);
257  }
258  break;
259  case ConstraintProto::ConstraintCase::kLinear:
260  APPLY_TO_REPEATED_FIELD(linear, vars);
261  break;
262  case ConstraintProto::ConstraintCase::kAllDiff:
263  for (int i = 0; i < ct->all_diff().exprs_size(); ++i) {
264  APPLY_TO_REPEATED_FIELD(all_diff, exprs(i)->mutable_vars);
265  }
266  break;
267  case ConstraintProto::ConstraintCase::kDummyConstraint:
268  APPLY_TO_REPEATED_FIELD(dummy_constraint, vars);
269  break;
270  case ConstraintProto::ConstraintCase::kElement:
271  APPLY_TO_SINGULAR_FIELD(element, index);
272  APPLY_TO_SINGULAR_FIELD(element, target);
273  APPLY_TO_REPEATED_FIELD(element, vars);
274  break;
275  case ConstraintProto::ConstraintCase::kCircuit:
276  break;
277  case ConstraintProto::ConstraintCase::kRoutes:
278  break;
279  case ConstraintProto::ConstraintCase::kInverse:
280  APPLY_TO_REPEATED_FIELD(inverse, f_direct);
281  APPLY_TO_REPEATED_FIELD(inverse, f_inverse);
282  break;
283  case ConstraintProto::ConstraintCase::kReservoir:
284  for (int i = 0; i < ct->reservoir().time_exprs_size(); ++i) {
285  APPLY_TO_REPEATED_FIELD(reservoir, time_exprs(i)->mutable_vars);
286  }
287  break;
288  case ConstraintProto::ConstraintCase::kTable:
289  APPLY_TO_REPEATED_FIELD(table, vars);
290  break;
291  case ConstraintProto::ConstraintCase::kAutomaton:
292  APPLY_TO_REPEATED_FIELD(automaton, vars);
293  break;
294  case ConstraintProto::ConstraintCase::kInterval:
295  APPLY_TO_REPEATED_FIELD(interval, start()->mutable_vars);
296  APPLY_TO_REPEATED_FIELD(interval, size()->mutable_vars);
297  APPLY_TO_REPEATED_FIELD(interval, end()->mutable_vars);
298  break;
299  case ConstraintProto::ConstraintCase::kNoOverlap:
300  break;
301  case ConstraintProto::ConstraintCase::kNoOverlap2D:
302  break;
303  case ConstraintProto::ConstraintCase::kCumulative:
304  APPLY_TO_REPEATED_FIELD(cumulative, capacity()->mutable_vars);
305  for (int i = 0; i < ct->cumulative().demands_size(); ++i) {
306  for (int& r :
307  *ct->mutable_cumulative()->mutable_demands(i)->mutable_vars()) {
308  f(&r);
309  }
310  }
311  break;
312  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
313  break;
314  }
315 }
316 
317 void ApplyToAllIntervalIndices(const std::function<void(int*)>& f,
318  ConstraintProto* ct) {
319  switch (ct->constraint_case()) {
320  case ConstraintProto::ConstraintCase::kBoolOr:
321  break;
322  case ConstraintProto::ConstraintCase::kBoolAnd:
323  break;
324  case ConstraintProto::ConstraintCase::kAtMostOne:
325  break;
326  case ConstraintProto::ConstraintCase::kExactlyOne:
327  break;
328  case ConstraintProto::ConstraintCase::kBoolXor:
329  break;
330  case ConstraintProto::ConstraintCase::kIntDiv:
331  break;
332  case ConstraintProto::ConstraintCase::kIntMod:
333  break;
334  case ConstraintProto::ConstraintCase::kLinMax:
335  break;
336  case ConstraintProto::ConstraintCase::kIntProd:
337  break;
338  case ConstraintProto::ConstraintCase::kLinear:
339  break;
340  case ConstraintProto::ConstraintCase::kAllDiff:
341  break;
342  case ConstraintProto::ConstraintCase::kDummyConstraint:
343  break;
344  case ConstraintProto::ConstraintCase::kElement:
345  break;
346  case ConstraintProto::ConstraintCase::kCircuit:
347  break;
348  case ConstraintProto::ConstraintCase::kRoutes:
349  break;
350  case ConstraintProto::ConstraintCase::kInverse:
351  break;
352  case ConstraintProto::ConstraintCase::kReservoir:
353  break;
354  case ConstraintProto::ConstraintCase::kTable:
355  break;
356  case ConstraintProto::ConstraintCase::kAutomaton:
357  break;
358  case ConstraintProto::ConstraintCase::kInterval:
359  break;
360  case ConstraintProto::ConstraintCase::kNoOverlap:
361  APPLY_TO_REPEATED_FIELD(no_overlap, intervals);
362  break;
363  case ConstraintProto::ConstraintCase::kNoOverlap2D:
364  APPLY_TO_REPEATED_FIELD(no_overlap_2d, x_intervals);
365  APPLY_TO_REPEATED_FIELD(no_overlap_2d, y_intervals);
366  break;
367  case ConstraintProto::ConstraintCase::kCumulative:
368  APPLY_TO_REPEATED_FIELD(cumulative, intervals);
369  break;
370  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
371  break;
372  }
373 }
374 
375 #undef APPLY_TO_SINGULAR_FIELD
376 #undef APPLY_TO_REPEATED_FIELD
377 
378 std::string ConstraintCaseName(
379  ConstraintProto::ConstraintCase constraint_case) {
380  switch (constraint_case) {
381  case ConstraintProto::ConstraintCase::kBoolOr:
382  return "kBoolOr";
383  case ConstraintProto::ConstraintCase::kBoolAnd:
384  return "kBoolAnd";
385  case ConstraintProto::ConstraintCase::kAtMostOne:
386  return "kAtMostOne";
387  case ConstraintProto::ConstraintCase::kExactlyOne:
388  return "kExactlyOne";
389  case ConstraintProto::ConstraintCase::kBoolXor:
390  return "kBoolXor";
391  case ConstraintProto::ConstraintCase::kIntDiv:
392  return "kIntDiv";
393  case ConstraintProto::ConstraintCase::kIntMod:
394  return "kIntMod";
395  case ConstraintProto::ConstraintCase::kLinMax:
396  return "kLinMax";
397  case ConstraintProto::ConstraintCase::kIntProd:
398  return "kIntProd";
399  case ConstraintProto::ConstraintCase::kLinear:
400  return "kLinear";
401  case ConstraintProto::ConstraintCase::kAllDiff:
402  return "kAllDiff";
403  case ConstraintProto::ConstraintCase::kDummyConstraint:
404  return "kDummyConstraint";
405  case ConstraintProto::ConstraintCase::kElement:
406  return "kElement";
407  case ConstraintProto::ConstraintCase::kCircuit:
408  return "kCircuit";
409  case ConstraintProto::ConstraintCase::kRoutes:
410  return "kRoutes";
411  case ConstraintProto::ConstraintCase::kInverse:
412  return "kInverse";
413  case ConstraintProto::ConstraintCase::kReservoir:
414  return "kReservoir";
415  case ConstraintProto::ConstraintCase::kTable:
416  return "kTable";
417  case ConstraintProto::ConstraintCase::kAutomaton:
418  return "kAutomaton";
419  case ConstraintProto::ConstraintCase::kInterval:
420  return "kInterval";
421  case ConstraintProto::ConstraintCase::kNoOverlap:
422  return "kNoOverlap";
423  case ConstraintProto::ConstraintCase::kNoOverlap2D:
424  return "kNoOverlap2D";
425  case ConstraintProto::ConstraintCase::kCumulative:
426  return "kCumulative";
427  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
428  return "kEmpty";
429  }
430 }
431 
432 std::vector<int> UsedVariables(const ConstraintProto& ct) {
434  for (int& ref : references.variables) {
435  ref = PositiveRef(ref);
436  }
437  for (const int lit : references.literals) {
438  references.variables.push_back(PositiveRef(lit));
439  }
440  for (const int lit : ct.enforcement_literal()) {
441  references.variables.push_back(PositiveRef(lit));
442  }
444  return references.variables;
445 }
446 
447 std::vector<int> UsedIntervals(const ConstraintProto& ct) {
448  std::vector<int> used_intervals;
449  switch (ct.constraint_case()) {
450  case ConstraintProto::ConstraintCase::kBoolOr:
451  break;
452  case ConstraintProto::ConstraintCase::kBoolAnd:
453  break;
454  case ConstraintProto::ConstraintCase::kAtMostOne:
455  break;
456  case ConstraintProto::ConstraintCase::kExactlyOne:
457  break;
458  case ConstraintProto::ConstraintCase::kBoolXor:
459  break;
460  case ConstraintProto::ConstraintCase::kIntDiv:
461  break;
462  case ConstraintProto::ConstraintCase::kIntMod:
463  break;
464  case ConstraintProto::ConstraintCase::kLinMax:
465  break;
466  case ConstraintProto::ConstraintCase::kIntProd:
467  break;
468  case ConstraintProto::ConstraintCase::kLinear:
469  break;
470  case ConstraintProto::ConstraintCase::kAllDiff:
471  break;
472  case ConstraintProto::ConstraintCase::kDummyConstraint:
473  break;
474  case ConstraintProto::ConstraintCase::kElement:
475  break;
476  case ConstraintProto::ConstraintCase::kCircuit:
477  break;
478  case ConstraintProto::ConstraintCase::kRoutes:
479  break;
480  case ConstraintProto::ConstraintCase::kInverse:
481  break;
482  case ConstraintProto::ConstraintCase::kReservoir:
483  break;
484  case ConstraintProto::ConstraintCase::kTable:
485  break;
486  case ConstraintProto::ConstraintCase::kAutomaton:
487  break;
488  case ConstraintProto::ConstraintCase::kInterval:
489  break;
490  case ConstraintProto::ConstraintCase::kNoOverlap:
491  AddIndices(ct.no_overlap().intervals(), &used_intervals);
492  break;
493  case ConstraintProto::ConstraintCase::kNoOverlap2D:
494  AddIndices(ct.no_overlap_2d().x_intervals(), &used_intervals);
495  AddIndices(ct.no_overlap_2d().y_intervals(), &used_intervals);
496  break;
497  case ConstraintProto::ConstraintCase::kCumulative:
498  AddIndices(ct.cumulative().intervals(), &used_intervals);
499  break;
500  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
501  break;
502  }
503  gtl::STLSortAndRemoveDuplicates(&used_intervals);
504  return used_intervals;
505 }
506 
507 int64_t ComputeInnerObjective(const CpObjectiveProto& objective,
508  const CpSolverResponse& response) {
509  int64_t objective_value = 0;
510  for (int i = 0; i < objective.vars_size(); ++i) {
511  int64_t coeff = objective.coeffs(i);
512  const int ref = objective.vars(i);
513  const int var = PositiveRef(ref);
514  if (!RefIsPositive(ref)) coeff = -coeff;
515  objective_value += coeff * response.solution()[var];
516  }
517  return objective_value;
518 }
519 
521  return expr.offset() == 0 && expr.vars_size() == 1 &&
522  std::abs(expr.coeffs(0)) == 1;
523 }
524 
526  return expr.vars_size() <= 1;
527 }
528 
529 // Returns the reference the expression can be reduced to. It will DCHECK that
530 // ExpressionContainsSingleRef(expr) is true.
533  return expr.coeffs(0) == 1 ? expr.vars(0) : NegatedRef(expr.vars(0));
534 }
535 
537  int64_t coefficient,
538  LinearConstraintProto* linear) {
539  for (int i = 0; i < expr.vars_size(); ++i) {
540  linear->add_vars(expr.vars(i));
541  linear->add_coeffs(expr.coeffs(i) * coefficient);
542  }
543  DCHECK(!linear->domain().empty());
544  const int64_t shift = coefficient * expr.offset();
545  if (shift != 0) {
546  for (int64_t& d : *linear->mutable_domain()) {
547  d -= shift;
548  }
549  }
550 }
551 
553  const LinearExpressionProto& b,
554  int64_t b_scaling) {
555  if (a.vars_size() != b.vars_size()) return false;
556  if (a.offset() != b.offset() * b_scaling) return false;
557  absl::flat_hash_map<int, int64_t> coeffs;
558  for (int i = 0; i < a.vars_size(); ++i) {
559  coeffs[a.vars(i)] += a.coeffs(i);
560  coeffs[b.vars(i)] += -b.coeffs(i) * b_scaling;
561  }
562 
563  for (const auto [var, coeff] : coeffs) {
564  if (coeff != 0) return false;
565  }
566  return true;
567 }
568 
569 } // namespace sat
570 } // namespace operations_research
::PROTOBUF_NAMESPACE_ID::RepeatedField< int64_t > * mutable_domain()
Definition: cp_model.pb.h:7623
std::vector< int > UsedVariables(const ConstraintProto &ct)
void ApplyToAllIntervalIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
void ApplyToAllVariableIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
bool LinearExpressionProtosAreEqual(const LinearExpressionProto &a, const LinearExpressionProto &b, int64_t b_scaling)
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
Definition: stl_util.h:58
int64_t coefficient
int64_t b
#define APPLY_TO_REPEATED_FIELD(ct_name, field_name)
#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name)
int64_t demand
Definition: resource.cc:125
int64_t capacity
int index
Definition: pack.cc:509
SharedResponseManager * response
void AddLinearExpressionToLinearConstraint(const LinearExpressionProto &expr, int64_t coefficient, LinearConstraintProto *linear)
std::vector< int > UsedIntervals(const ConstraintProto &ct)
std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case)
#define DCHECK(condition)
Definition: base/logging.h:889
bool ExpressionContainsSingleRef(const LinearExpressionProto &expr)
Collection of objects used to extend the Constraint Solver library.
int64_t time
Definition: resource.cc:1691
int64_t ComputeInnerObjective(const CpObjectiveProto &objective, const CpSolverResponse &response)
bool ExpressionIsAffine(const LinearExpressionProto &expr)
bool RefIsPositive(int ref)
IntVar * var
Definition: expr_array.cc:1874
int GetSingleRefFromExpression(const LinearExpressionProto &expr)
void ApplyToAllLiteralIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
IntervalVar * interval
Definition: resource.cc:100
const Constraint * ct
IndexReferences GetReferencesUsedByConstraint(const ConstraintProto &ct)
void SetToNegatedLinearExpression(const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr)
int64_t a