OR-Tools  8.1
cp_model_utils.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 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 "absl/container/flat_hash_set.h"
17 #include "ortools/base/stl_util.h"
18 
19 namespace operations_research {
20 namespace sat {
21 
22 namespace {
23 
24 template <typename IntList>
25 void AddIndices(const IntList& indices, absl::flat_hash_set<int>* output) {
26  output->insert(indices.begin(), indices.end());
27 }
28 
29 template <typename IntList>
30 void AddIndices(const IntList& indices, std::vector<int>* output) {
31  output->insert(output->end(), indices.begin(), indices.end());
32 }
33 
34 } // namespace
35 
36 void SetToNegatedLinearExpression(const LinearExpressionProto& input_expr,
37  LinearExpressionProto* output_negated_expr) {
38  output_negated_expr->Clear();
39  for (int i = 0; i < input_expr.vars_size(); ++i) {
40  output_negated_expr->add_vars(NegatedRef(input_expr.vars(i)));
41  output_negated_expr->add_coeffs(input_expr.coeffs(i));
42  }
43  output_negated_expr->set_offset(-input_expr.offset());
44 }
45 
47  IndexReferences output;
48  switch (ct.constraint_case()) {
49  case ConstraintProto::ConstraintCase::kBoolOr:
50  AddIndices(ct.bool_or().literals(), &output.literals);
51  break;
52  case ConstraintProto::ConstraintCase::kBoolAnd:
53  AddIndices(ct.bool_and().literals(), &output.literals);
54  break;
55  case ConstraintProto::ConstraintCase::kAtMostOne:
56  AddIndices(ct.at_most_one().literals(), &output.literals);
57  break;
58  case ConstraintProto::ConstraintCase::kBoolXor:
59  AddIndices(ct.bool_xor().literals(), &output.literals);
60  break;
61  case ConstraintProto::ConstraintCase::kIntDiv:
62  output.variables.push_back(ct.int_div().target());
63  AddIndices(ct.int_div().vars(), &output.variables);
64  break;
65  case ConstraintProto::ConstraintCase::kIntMod:
66  output.variables.push_back(ct.int_mod().target());
67  AddIndices(ct.int_mod().vars(), &output.variables);
68  break;
69  case ConstraintProto::ConstraintCase::kIntMax:
70  output.variables.push_back(ct.int_max().target());
71  AddIndices(ct.int_max().vars(), &output.variables);
72  break;
73  case ConstraintProto::ConstraintCase::kLinMax: {
74  AddIndices(ct.lin_max().target().vars(), &output.variables);
75  for (int i = 0; i < ct.lin_max().exprs_size(); ++i) {
76  AddIndices(ct.lin_max().exprs(i).vars(), &output.variables);
77  }
78  break;
79  }
80  case ConstraintProto::ConstraintCase::kIntMin:
81  output.variables.push_back(ct.int_min().target());
82  AddIndices(ct.int_min().vars(), &output.variables);
83  break;
84  case ConstraintProto::ConstraintCase::kLinMin: {
85  AddIndices(ct.lin_min().target().vars(), &output.variables);
86  for (int i = 0; i < ct.lin_min().exprs_size(); ++i) {
87  AddIndices(ct.lin_min().exprs(i).vars(), &output.variables);
88  }
89  break;
90  }
91  case ConstraintProto::ConstraintCase::kIntProd:
92  output.variables.push_back(ct.int_prod().target());
93  AddIndices(ct.int_prod().vars(), &output.variables);
94  break;
95  case ConstraintProto::ConstraintCase::kLinear:
96  AddIndices(ct.linear().vars(), &output.variables);
97  break;
98  case ConstraintProto::ConstraintCase::kAllDiff:
99  AddIndices(ct.all_diff().vars(), &output.variables);
100  break;
101  case ConstraintProto::ConstraintCase::kElement:
102  output.variables.push_back(ct.element().index());
103  output.variables.push_back(ct.element().target());
104  AddIndices(ct.element().vars(), &output.variables);
105  break;
106  case ConstraintProto::ConstraintCase::kCircuit:
107  AddIndices(ct.circuit().literals(), &output.literals);
108  break;
109  case ConstraintProto::ConstraintCase::kRoutes:
110  AddIndices(ct.routes().literals(), &output.literals);
111  break;
112  case ConstraintProto::ConstraintCase::kInverse:
113  AddIndices(ct.inverse().f_direct(), &output.variables);
114  AddIndices(ct.inverse().f_inverse(), &output.variables);
115  break;
116  case ConstraintProto::ConstraintCase::kReservoir:
117  AddIndices(ct.reservoir().times(), &output.variables);
118  AddIndices(ct.reservoir().actives(), &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  output.variables.push_back(ct.interval().start());
128  output.variables.push_back(ct.interval().end());
129  output.variables.push_back(ct.interval().size());
130  break;
131  case ConstraintProto::ConstraintCase::kNoOverlap:
132  break;
133  case ConstraintProto::ConstraintCase::kNoOverlap2D:
134  break;
135  case ConstraintProto::ConstraintCase::kCumulative:
136  output.variables.push_back(ct.cumulative().capacity());
137  AddIndices(ct.cumulative().demands(), &output.variables);
138  break;
139  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
140  break;
141  }
142  return output;
143 }
144 
145 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
146  { \
147  int temp = ct->mutable_##ct_name()->field_name(); \
148  f(&temp); \
149  ct->mutable_##ct_name()->set_##field_name(temp); \
150  }
151 
152 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
153  { \
154  for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
155  }
156 
157 void ApplyToAllLiteralIndices(const std::function<void(int*)>& f,
158  ConstraintProto* ct) {
159  for (int& r : *ct->mutable_enforcement_literal()) f(&r);
160  switch (ct->constraint_case()) {
161  case ConstraintProto::ConstraintCase::kBoolOr:
162  APPLY_TO_REPEATED_FIELD(bool_or, literals);
163  break;
164  case ConstraintProto::ConstraintCase::kBoolAnd:
165  APPLY_TO_REPEATED_FIELD(bool_and, literals);
166  break;
167  case ConstraintProto::ConstraintCase::kAtMostOne:
168  APPLY_TO_REPEATED_FIELD(at_most_one, literals);
169  break;
170  case ConstraintProto::ConstraintCase::kBoolXor:
171  APPLY_TO_REPEATED_FIELD(bool_xor, literals);
172  break;
173  case ConstraintProto::ConstraintCase::kIntDiv:
174  break;
175  case ConstraintProto::ConstraintCase::kIntMod:
176  break;
177  case ConstraintProto::ConstraintCase::kIntMax:
178  break;
179  case ConstraintProto::ConstraintCase::kLinMax:
180  break;
181  case ConstraintProto::ConstraintCase::kIntMin:
182  break;
183  case ConstraintProto::ConstraintCase::kLinMin:
184  break;
185  case ConstraintProto::ConstraintCase::kIntProd:
186  break;
187  case ConstraintProto::ConstraintCase::kLinear:
188  break;
189  case ConstraintProto::ConstraintCase::kAllDiff:
190  break;
191  case ConstraintProto::ConstraintCase::kElement:
192  break;
193  case ConstraintProto::ConstraintCase::kCircuit:
194  APPLY_TO_REPEATED_FIELD(circuit, literals);
195  break;
196  case ConstraintProto::ConstraintCase::kRoutes:
197  APPLY_TO_REPEATED_FIELD(routes, literals);
198  break;
199  case ConstraintProto::ConstraintCase::kInverse:
200  break;
201  case ConstraintProto::ConstraintCase::kReservoir:
202  APPLY_TO_REPEATED_FIELD(reservoir, actives);
203  break;
204  case ConstraintProto::ConstraintCase::kTable:
205  break;
206  case ConstraintProto::ConstraintCase::kAutomaton:
207  break;
208  case ConstraintProto::ConstraintCase::kInterval:
209  break;
210  case ConstraintProto::ConstraintCase::kNoOverlap:
211  break;
212  case ConstraintProto::ConstraintCase::kNoOverlap2D:
213  break;
214  case ConstraintProto::ConstraintCase::kCumulative:
215  break;
216  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
217  break;
218  }
219 }
220 
221 void ApplyToAllVariableIndices(const std::function<void(int*)>& f,
222  ConstraintProto* ct) {
223  switch (ct->constraint_case()) {
224  case ConstraintProto::ConstraintCase::kBoolOr:
225  break;
226  case ConstraintProto::ConstraintCase::kBoolAnd:
227  break;
228  case ConstraintProto::ConstraintCase::kAtMostOne:
229  break;
230  case ConstraintProto::ConstraintCase::kBoolXor:
231  break;
232  case ConstraintProto::ConstraintCase::kIntDiv:
233  APPLY_TO_SINGULAR_FIELD(int_div, target);
234  APPLY_TO_REPEATED_FIELD(int_div, vars);
235  break;
236  case ConstraintProto::ConstraintCase::kIntMod:
237  APPLY_TO_SINGULAR_FIELD(int_mod, target);
238  APPLY_TO_REPEATED_FIELD(int_mod, vars);
239  break;
240  case ConstraintProto::ConstraintCase::kIntMax:
241  APPLY_TO_SINGULAR_FIELD(int_max, target);
242  APPLY_TO_REPEATED_FIELD(int_max, vars);
243  break;
244  case ConstraintProto::ConstraintCase::kLinMax:
245  APPLY_TO_REPEATED_FIELD(lin_max, target()->mutable_vars);
246  for (int i = 0; i < ct->lin_max().exprs_size(); ++i) {
247  APPLY_TO_REPEATED_FIELD(lin_max, exprs(i)->mutable_vars);
248  }
249  break;
250  case ConstraintProto::ConstraintCase::kIntMin:
251  APPLY_TO_SINGULAR_FIELD(int_min, target);
252  APPLY_TO_REPEATED_FIELD(int_min, vars);
253  break;
254  case ConstraintProto::ConstraintCase::kLinMin:
255  APPLY_TO_REPEATED_FIELD(lin_min, target()->mutable_vars);
256  for (int i = 0; i < ct->lin_min().exprs_size(); ++i) {
257  APPLY_TO_REPEATED_FIELD(lin_min, exprs(i)->mutable_vars);
258  }
259  break;
260  case ConstraintProto::ConstraintCase::kIntProd:
261  APPLY_TO_SINGULAR_FIELD(int_prod, target);
262  APPLY_TO_REPEATED_FIELD(int_prod, vars);
263  break;
264  case ConstraintProto::ConstraintCase::kLinear:
265  APPLY_TO_REPEATED_FIELD(linear, vars);
266  break;
267  case ConstraintProto::ConstraintCase::kAllDiff:
268  APPLY_TO_REPEATED_FIELD(all_diff, 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  APPLY_TO_REPEATED_FIELD(reservoir, times);
285  break;
286  case ConstraintProto::ConstraintCase::kTable:
287  APPLY_TO_REPEATED_FIELD(table, vars);
288  break;
289  case ConstraintProto::ConstraintCase::kAutomaton:
290  APPLY_TO_REPEATED_FIELD(automaton, vars);
291  break;
292  case ConstraintProto::ConstraintCase::kInterval:
296  break;
297  case ConstraintProto::ConstraintCase::kNoOverlap:
298  break;
299  case ConstraintProto::ConstraintCase::kNoOverlap2D:
300  break;
301  case ConstraintProto::ConstraintCase::kCumulative:
302  APPLY_TO_SINGULAR_FIELD(cumulative, capacity);
303  APPLY_TO_REPEATED_FIELD(cumulative, demands);
304  break;
305  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
306  break;
307  }
308 }
309 
310 void ApplyToAllIntervalIndices(const std::function<void(int*)>& f,
311  ConstraintProto* ct) {
312  switch (ct->constraint_case()) {
313  case ConstraintProto::ConstraintCase::kBoolOr:
314  break;
315  case ConstraintProto::ConstraintCase::kBoolAnd:
316  break;
317  case ConstraintProto::ConstraintCase::kAtMostOne:
318  break;
319  case ConstraintProto::ConstraintCase::kBoolXor:
320  break;
321  case ConstraintProto::ConstraintCase::kIntDiv:
322  break;
323  case ConstraintProto::ConstraintCase::kIntMod:
324  break;
325  case ConstraintProto::ConstraintCase::kIntMax:
326  break;
327  case ConstraintProto::ConstraintCase::kLinMax:
328  break;
329  case ConstraintProto::ConstraintCase::kIntMin:
330  break;
331  case ConstraintProto::ConstraintCase::kLinMin:
332  break;
333  case ConstraintProto::ConstraintCase::kIntProd:
334  break;
335  case ConstraintProto::ConstraintCase::kLinear:
336  break;
337  case ConstraintProto::ConstraintCase::kAllDiff:
338  break;
339  case ConstraintProto::ConstraintCase::kElement:
340  break;
341  case ConstraintProto::ConstraintCase::kCircuit:
342  break;
343  case ConstraintProto::ConstraintCase::kRoutes:
344  break;
345  case ConstraintProto::ConstraintCase::kInverse:
346  break;
347  case ConstraintProto::ConstraintCase::kReservoir:
348  break;
349  case ConstraintProto::ConstraintCase::kTable:
350  break;
351  case ConstraintProto::ConstraintCase::kAutomaton:
352  break;
353  case ConstraintProto::ConstraintCase::kInterval:
354  break;
355  case ConstraintProto::ConstraintCase::kNoOverlap:
356  APPLY_TO_REPEATED_FIELD(no_overlap, intervals);
357  break;
358  case ConstraintProto::ConstraintCase::kNoOverlap2D:
359  APPLY_TO_REPEATED_FIELD(no_overlap_2d, x_intervals);
360  APPLY_TO_REPEATED_FIELD(no_overlap_2d, y_intervals);
361  break;
362  case ConstraintProto::ConstraintCase::kCumulative:
363  APPLY_TO_REPEATED_FIELD(cumulative, intervals);
364  break;
365  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
366  break;
367  }
368 }
369 
370 #undef APPLY_TO_SINGULAR_FIELD
371 #undef APPLY_TO_REPEATED_FIELD
372 
373 std::string ConstraintCaseName(
374  ConstraintProto::ConstraintCase constraint_case) {
375  switch (constraint_case) {
376  case ConstraintProto::ConstraintCase::kBoolOr:
377  return "kBoolOr";
378  case ConstraintProto::ConstraintCase::kBoolAnd:
379  return "kBoolAnd";
380  case ConstraintProto::ConstraintCase::kAtMostOne:
381  return "kAtMostOne";
382  case ConstraintProto::ConstraintCase::kBoolXor:
383  return "kBoolXor";
384  case ConstraintProto::ConstraintCase::kIntDiv:
385  return "kIntDiv";
386  case ConstraintProto::ConstraintCase::kIntMod:
387  return "kIntMod";
388  case ConstraintProto::ConstraintCase::kIntMax:
389  return "kIntMax";
390  case ConstraintProto::ConstraintCase::kLinMax:
391  return "kLinMax";
392  case ConstraintProto::ConstraintCase::kIntMin:
393  return "kIntMin";
394  case ConstraintProto::ConstraintCase::kLinMin:
395  return "kLinMin";
396  case ConstraintProto::ConstraintCase::kIntProd:
397  return "kIntProd";
398  case ConstraintProto::ConstraintCase::kLinear:
399  return "kLinear";
400  case ConstraintProto::ConstraintCase::kAllDiff:
401  return "kAllDiff";
402  case ConstraintProto::ConstraintCase::kElement:
403  return "kElement";
404  case ConstraintProto::ConstraintCase::kCircuit:
405  return "kCircuit";
406  case ConstraintProto::ConstraintCase::kRoutes:
407  return "kRoutes";
408  case ConstraintProto::ConstraintCase::kInverse:
409  return "kInverse";
410  case ConstraintProto::ConstraintCase::kReservoir:
411  return "kReservoir";
412  case ConstraintProto::ConstraintCase::kTable:
413  return "kTable";
414  case ConstraintProto::ConstraintCase::kAutomaton:
415  return "kAutomaton";
416  case ConstraintProto::ConstraintCase::kInterval:
417  return "kInterval";
418  case ConstraintProto::ConstraintCase::kNoOverlap:
419  return "kNoOverlap";
420  case ConstraintProto::ConstraintCase::kNoOverlap2D:
421  return "kNoOverlap2D";
422  case ConstraintProto::ConstraintCase::kCumulative:
423  return "kCumulative";
424  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
425  return "kEmpty";
426  }
427 }
428 
429 std::vector<int> UsedVariables(const ConstraintProto& ct) {
431  for (int& ref : references.variables) {
432  ref = PositiveRef(ref);
433  }
434  for (const int lit : references.literals) {
435  references.variables.push_back(PositiveRef(lit));
436  }
437  for (const int lit : ct.enforcement_literal()) {
438  references.variables.push_back(PositiveRef(lit));
439  }
441  return references.variables;
442 }
443 
444 std::vector<int> UsedIntervals(const ConstraintProto& ct) {
445  std::vector<int> used_intervals;
446  switch (ct.constraint_case()) {
447  case ConstraintProto::ConstraintCase::kBoolOr:
448  break;
449  case ConstraintProto::ConstraintCase::kBoolAnd:
450  break;
451  case ConstraintProto::ConstraintCase::kAtMostOne:
452  break;
453  case ConstraintProto::ConstraintCase::kBoolXor:
454  break;
455  case ConstraintProto::ConstraintCase::kIntDiv:
456  break;
457  case ConstraintProto::ConstraintCase::kIntMod:
458  break;
459  case ConstraintProto::ConstraintCase::kIntMax:
460  break;
461  case ConstraintProto::ConstraintCase::kLinMax:
462  break;
463  case ConstraintProto::ConstraintCase::kIntMin:
464  break;
465  case ConstraintProto::ConstraintCase::kLinMin:
466  break;
467  case ConstraintProto::ConstraintCase::kIntProd:
468  break;
469  case ConstraintProto::ConstraintCase::kLinear:
470  break;
471  case ConstraintProto::ConstraintCase::kAllDiff:
472  break;
473  case ConstraintProto::ConstraintCase::kElement:
474  break;
475  case ConstraintProto::ConstraintCase::kCircuit:
476  break;
477  case ConstraintProto::ConstraintCase::kRoutes:
478  break;
479  case ConstraintProto::ConstraintCase::kInverse:
480  break;
481  case ConstraintProto::ConstraintCase::kReservoir:
482  break;
483  case ConstraintProto::ConstraintCase::kTable:
484  break;
485  case ConstraintProto::ConstraintCase::kAutomaton:
486  break;
487  case ConstraintProto::ConstraintCase::kInterval:
488  break;
489  case ConstraintProto::ConstraintCase::kNoOverlap:
490  AddIndices(ct.no_overlap().intervals(), &used_intervals);
491  break;
492  case ConstraintProto::ConstraintCase::kNoOverlap2D:
493  AddIndices(ct.no_overlap_2d().x_intervals(), &used_intervals);
494  AddIndices(ct.no_overlap_2d().y_intervals(), &used_intervals);
495  break;
496  case ConstraintProto::ConstraintCase::kCumulative:
497  AddIndices(ct.cumulative().intervals(), &used_intervals);
498  break;
499  case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
500  break;
501  }
502  gtl::STLSortAndRemoveDuplicates(&used_intervals);
503  return used_intervals;
504 }
505 
506 int64 ComputeInnerObjective(const CpObjectiveProto& objective,
507  const CpSolverResponse& response) {
508  int64 objective_value = 0;
509  auto& repeated_field_values = response.solution().empty()
510  ? response.solution_lower_bounds()
511  : response.solution();
512  for (int i = 0; i < objective.vars_size(); ++i) {
513  int64 coeff = objective.coeffs(i);
514  const int ref = objective.vars(i);
515  const int var = PositiveRef(ref);
516  if (!RefIsPositive(ref)) coeff = -coeff;
517  objective_value += coeff * repeated_field_values[var];
518  }
519  return objective_value;
520 }
521 
522 } // namespace sat
523 } // namespace operations_research
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::sat::ApplyToAllVariableIndices
void ApplyToAllVariableIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
Definition: cp_model_utils.cc:221
response
SharedResponseManager * response
Definition: cp_model_solver.cc:2105
operations_research::sat::ApplyToAllLiteralIndices
void ApplyToAllLiteralIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
Definition: cp_model_utils.cc:157
operations_research::sat::UsedVariables
std::vector< int > UsedVariables(const ConstraintProto &ct)
Definition: cp_model_utils.cc:429
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::sat::GetReferencesUsedByConstraint
IndexReferences GetReferencesUsedByConstraint(const ConstraintProto &ct)
Definition: cp_model_utils.cc:46
int64
int64_t int64
Definition: integral_types.h:34
index
int index
Definition: pack.cc:508
operations_research::sat::UsedIntervals
std::vector< int > UsedIntervals(const ConstraintProto &ct)
Definition: cp_model_utils.cc:444
operations_research::sat::PositiveRef
int PositiveRef(int ref)
Definition: cp_model_utils.h:33
gtl::STLSortAndRemoveDuplicates
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
Definition: stl_util.h:58
ct
const Constraint * ct
Definition: demon_profiler.cc:42
operations_research::sat::ComputeInnerObjective
int64 ComputeInnerObjective(const CpObjectiveProto &objective, const CpSolverResponse &response)
Definition: cp_model_utils.cc:506
operations_research::sat::NegatedRef
int NegatedRef(int ref)
Definition: cp_model_utils.h:32
operations_research::sat::RefIsPositive
bool RefIsPositive(int ref)
Definition: cp_model_utils.h:34
operations_research::sat::ApplyToAllIntervalIndices
void ApplyToAllIntervalIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
Definition: cp_model_utils.cc:310
stl_util.h
operations_research::sat::IndexReferences
Definition: cp_model_utils.h:52
APPLY_TO_REPEATED_FIELD
#define APPLY_TO_REPEATED_FIELD(ct_name, field_name)
Definition: cp_model_utils.cc:152
operations_research::sat::IndexReferences::literals
std::vector< int > literals
Definition: cp_model_utils.h:54
operations_research::sat::SetToNegatedLinearExpression
void SetToNegatedLinearExpression(const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr)
Definition: cp_model_utils.cc:36
APPLY_TO_SINGULAR_FIELD
#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name)
Definition: cp_model_utils.cc:145
operations_research::sat::ConstraintCaseName
std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case)
Definition: cp_model_utils.cc:373
capacity
int64 capacity
Definition: routing_flow.cc:129
interval
IntervalVar * interval
Definition: resource.cc:98
operations_research::sat::IndexReferences::variables
std::vector< int > variables
Definition: cp_model_utils.h:53
cp_model_utils.h