88 std::vector<int>* variables,
89 std::vector<int>* literals) {
92 switch (ct.constraint_case()) {
93 case ConstraintProto::ConstraintCase::kBoolOr:
94 AddIndices(ct.bool_or().literals(), literals);
96 case ConstraintProto::ConstraintCase::kBoolAnd:
97 AddIndices(ct.bool_and().literals(), literals);
99 case ConstraintProto::ConstraintCase::kAtMostOne:
100 AddIndices(ct.at_most_one().literals(), literals);
102 case ConstraintProto::ConstraintCase::kExactlyOne:
103 AddIndices(ct.exactly_one().literals(), literals);
105 case ConstraintProto::ConstraintCase::kBoolXor:
106 AddIndices(ct.bool_xor().literals(), literals);
108 case ConstraintProto::ConstraintCase::kIntDiv:
109 AddIndices(ct.int_div().target().vars(), variables);
110 for (
const LinearExpressionProto& expr : ct.int_div().exprs()) {
111 AddIndices(expr.vars(), variables);
114 case ConstraintProto::ConstraintCase::kIntMod:
115 AddIndices(ct.int_mod().target().vars(), variables);
116 for (
const LinearExpressionProto& expr : ct.int_mod().exprs()) {
117 AddIndices(expr.vars(), variables);
120 case ConstraintProto::ConstraintCase::kLinMax: {
121 AddIndices(ct.lin_max().target().vars(), variables);
122 for (
const LinearExpressionProto& expr : ct.lin_max().exprs()) {
123 AddIndices(expr.vars(), variables);
127 case ConstraintProto::ConstraintCase::kIntProd:
128 AddIndices(ct.int_prod().target().vars(), variables);
129 for (
const LinearExpressionProto& expr : ct.int_prod().exprs()) {
130 AddIndices(expr.vars(), variables);
133 case ConstraintProto::ConstraintCase::kLinear:
134 AddIndices(ct.linear().vars(), variables);
136 case ConstraintProto::ConstraintCase::kAllDiff:
137 for (
const LinearExpressionProto& expr : ct.all_diff().exprs()) {
138 AddIndices(expr.vars(), variables);
141 case ConstraintProto::ConstraintCase::kDummyConstraint:
142 AddIndices(ct.dummy_constraint().vars(), variables);
144 case ConstraintProto::ConstraintCase::kElement:
145 if (ct.element().index() != 0 || ct.element().target() != 0 ||
146 !ct.element().vars().empty()) {
147 variables->push_back(ct.element().index());
148 variables->push_back(ct.element().target());
149 AddIndices(ct.element().vars(), variables);
150 }
else if (ct.element().has_linear_index() ||
151 ct.element().has_linear_target() ||
152 !ct.element().exprs().empty()) {
153 AddIndices(ct.element().linear_index().vars(), variables);
154 AddIndices(ct.element().linear_target().vars(), variables);
155 for (
const LinearExpressionProto& expr : ct.element().exprs()) {
156 AddIndices(expr.vars(), variables);
160 case ConstraintProto::ConstraintCase::kCircuit:
161 AddIndices(ct.circuit().literals(), literals);
163 case ConstraintProto::ConstraintCase::kRoutes:
164 AddIndices(ct.routes().literals(), literals);
166 case ConstraintProto::ConstraintCase::kInverse:
167 AddIndices(ct.inverse().f_direct(), variables);
168 AddIndices(ct.inverse().f_inverse(), variables);
170 case ConstraintProto::ConstraintCase::kReservoir:
171 for (
const LinearExpressionProto& time : ct.reservoir().time_exprs()) {
172 AddIndices(time.vars(), variables);
174 for (
const LinearExpressionProto& level :
175 ct.reservoir().level_changes()) {
176 AddIndices(level.vars(), variables);
178 AddIndices(ct.reservoir().active_literals(), literals);
180 case ConstraintProto::ConstraintCase::kTable:
181 if (!ct.table().vars().empty()) {
182 AddIndices(ct.table().vars(), variables);
184 for (
const LinearExpressionProto& expr : ct.table().exprs()) {
185 AddIndices(expr.vars(), variables);
189 case ConstraintProto::ConstraintCase::kAutomaton:
190 if (!ct.automaton().vars().empty()) {
191 AddIndices(ct.automaton().vars(), variables);
193 for (
const LinearExpressionProto& expr : ct.automaton().exprs()) {
194 AddIndices(expr.vars(), variables);
198 case ConstraintProto::ConstraintCase::kInterval:
199 AddIndices(ct.interval().start().vars(), variables);
200 AddIndices(ct.interval().size().vars(), variables);
201 AddIndices(ct.interval().end().vars(), variables);
203 case ConstraintProto::ConstraintCase::kNoOverlap:
205 case ConstraintProto::ConstraintCase::kNoOverlap2D:
207 case ConstraintProto::ConstraintCase::kCumulative:
208 AddIndices(ct.cumulative().capacity().vars(), variables);
209 for (
const LinearExpressionProto& demand : ct.cumulative().demands()) {
210 AddIndices(demand.vars(), variables);
213 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
231 ConstraintProto* ct) {
232 for (
int& r : *ct->mutable_enforcement_literal()) f(&r);
233 switch (ct->constraint_case()) {
234 case ConstraintProto::ConstraintCase::kBoolOr:
237 case ConstraintProto::ConstraintCase::kBoolAnd:
240 case ConstraintProto::ConstraintCase::kAtMostOne:
243 case ConstraintProto::ConstraintCase::kExactlyOne:
246 case ConstraintProto::ConstraintCase::kBoolXor:
249 case ConstraintProto::ConstraintCase::kIntDiv:
251 case ConstraintProto::ConstraintCase::kIntMod:
253 case ConstraintProto::ConstraintCase::kLinMax:
255 case ConstraintProto::ConstraintCase::kIntProd:
257 case ConstraintProto::ConstraintCase::kLinear:
259 case ConstraintProto::ConstraintCase::kAllDiff:
261 case ConstraintProto::ConstraintCase::kDummyConstraint:
263 case ConstraintProto::ConstraintCase::kElement:
265 case ConstraintProto::ConstraintCase::kCircuit:
268 case ConstraintProto::ConstraintCase::kRoutes:
271 case ConstraintProto::ConstraintCase::kInverse:
273 case ConstraintProto::ConstraintCase::kReservoir:
276 case ConstraintProto::ConstraintCase::kTable:
278 case ConstraintProto::ConstraintCase::kAutomaton:
280 case ConstraintProto::ConstraintCase::kInterval:
282 case ConstraintProto::ConstraintCase::kNoOverlap:
284 case ConstraintProto::ConstraintCase::kNoOverlap2D:
286 case ConstraintProto::ConstraintCase::kCumulative:
288 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
294 ConstraintProto* ct) {
295 switch (ct->constraint_case()) {
296 case ConstraintProto::ConstraintCase::kBoolOr:
298 case ConstraintProto::ConstraintCase::kBoolAnd:
300 case ConstraintProto::ConstraintCase::kAtMostOne:
302 case ConstraintProto::ConstraintCase::kExactlyOne:
304 case ConstraintProto::ConstraintCase::kBoolXor:
306 case ConstraintProto::ConstraintCase::kIntDiv:
308 for (
int i = 0;
i < ct->int_div().exprs_size(); ++
i) {
312 case ConstraintProto::ConstraintCase::kIntMod:
314 for (
int i = 0;
i < ct->int_mod().exprs_size(); ++
i) {
318 case ConstraintProto::ConstraintCase::kLinMax:
320 for (
int i = 0;
i < ct->lin_max().exprs_size(); ++
i) {
324 case ConstraintProto::ConstraintCase::kIntProd:
326 for (
int i = 0;
i < ct->int_prod().exprs_size(); ++
i) {
330 case ConstraintProto::ConstraintCase::kLinear:
333 case ConstraintProto::ConstraintCase::kAllDiff:
334 for (
int i = 0;
i < ct->all_diff().exprs_size(); ++
i) {
338 case ConstraintProto::ConstraintCase::kDummyConstraint:
341 case ConstraintProto::ConstraintCase::kElement:
342 if (ct->element().index() != 0 || ct->element().target() != 0 ||
343 !ct->element().vars().empty()) {
347 }
else if (ct->element().has_linear_index() ||
348 ct->element().has_linear_target() ||
349 !ct->element().exprs().empty()) {
352 for (
int i = 0;
i < ct->element().exprs_size(); ++
i) {
357 case ConstraintProto::ConstraintCase::kCircuit:
359 case ConstraintProto::ConstraintCase::kRoutes:
361 case ConstraintProto::ConstraintCase::kInverse:
365 case ConstraintProto::ConstraintCase::kReservoir:
366 for (
int i = 0;
i < ct->reservoir().time_exprs_size(); ++
i) {
369 for (
int i = 0;
i < ct->reservoir().level_changes_size(); ++
i) {
373 case ConstraintProto::ConstraintCase::kTable:
374 if (!ct->table().vars().empty()) {
377 for (
int i = 0;
i < ct->table().exprs_size(); ++
i) {
382 case ConstraintProto::ConstraintCase::kAutomaton:
383 if (!ct->automaton().vars().empty()) {
386 for (
int i = 0;
i < ct->automaton().exprs_size(); ++
i) {
391 case ConstraintProto::ConstraintCase::kInterval:
396 case ConstraintProto::ConstraintCase::kNoOverlap:
398 case ConstraintProto::ConstraintCase::kNoOverlap2D:
400 case ConstraintProto::ConstraintCase::kCumulative:
402 for (
int i = 0;
i < ct->cumulative().demands_size(); ++
i) {
404 *ct->mutable_cumulative()->mutable_demands(
i)->mutable_vars()) {
409 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
415 ConstraintProto* ct) {
416 switch (ct->constraint_case()) {
417 case ConstraintProto::ConstraintCase::kBoolOr:
419 case ConstraintProto::ConstraintCase::kBoolAnd:
421 case ConstraintProto::ConstraintCase::kAtMostOne:
423 case ConstraintProto::ConstraintCase::kExactlyOne:
425 case ConstraintProto::ConstraintCase::kBoolXor:
427 case ConstraintProto::ConstraintCase::kIntDiv:
429 case ConstraintProto::ConstraintCase::kIntMod:
431 case ConstraintProto::ConstraintCase::kLinMax:
433 case ConstraintProto::ConstraintCase::kIntProd:
435 case ConstraintProto::ConstraintCase::kLinear:
437 case ConstraintProto::ConstraintCase::kAllDiff:
439 case ConstraintProto::ConstraintCase::kDummyConstraint:
441 case ConstraintProto::ConstraintCase::kElement:
443 case ConstraintProto::ConstraintCase::kCircuit:
445 case ConstraintProto::ConstraintCase::kRoutes:
447 case ConstraintProto::ConstraintCase::kInverse:
449 case ConstraintProto::ConstraintCase::kReservoir:
451 case ConstraintProto::ConstraintCase::kTable:
453 case ConstraintProto::ConstraintCase::kAutomaton:
455 case ConstraintProto::ConstraintCase::kInterval:
457 case ConstraintProto::ConstraintCase::kNoOverlap:
460 case ConstraintProto::ConstraintCase::kNoOverlap2D:
464 case ConstraintProto::ConstraintCase::kCumulative:
467 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
476 ConstraintProto::ConstraintCase constraint_case) {
477 switch (constraint_case) {
478 case ConstraintProto::ConstraintCase::kBoolOr:
480 case ConstraintProto::ConstraintCase::kBoolAnd:
482 case ConstraintProto::ConstraintCase::kAtMostOne:
484 case ConstraintProto::ConstraintCase::kExactlyOne:
485 return "kExactlyOne";
486 case ConstraintProto::ConstraintCase::kBoolXor:
488 case ConstraintProto::ConstraintCase::kIntDiv:
490 case ConstraintProto::ConstraintCase::kIntMod:
492 case ConstraintProto::ConstraintCase::kLinMax:
494 case ConstraintProto::ConstraintCase::kIntProd:
496 case ConstraintProto::ConstraintCase::kLinear:
498 case ConstraintProto::ConstraintCase::kAllDiff:
500 case ConstraintProto::ConstraintCase::kDummyConstraint:
501 return "kDummyConstraint";
502 case ConstraintProto::ConstraintCase::kElement:
504 case ConstraintProto::ConstraintCase::kCircuit:
506 case ConstraintProto::ConstraintCase::kRoutes:
508 case ConstraintProto::ConstraintCase::kInverse:
510 case ConstraintProto::ConstraintCase::kReservoir:
512 case ConstraintProto::ConstraintCase::kTable:
514 case ConstraintProto::ConstraintCase::kAutomaton:
516 case ConstraintProto::ConstraintCase::kInterval:
518 case ConstraintProto::ConstraintCase::kNoOverlap:
520 case ConstraintProto::ConstraintCase::kNoOverlap2D:
521 return "kNoOverlap2D";
522 case ConstraintProto::ConstraintCase::kCumulative:
523 return "kCumulative";
524 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
543 std::vector<int> used_intervals;
544 switch (ct.constraint_case()) {
545 case ConstraintProto::ConstraintCase::kBoolOr:
547 case ConstraintProto::ConstraintCase::kBoolAnd:
549 case ConstraintProto::ConstraintCase::kAtMostOne:
551 case ConstraintProto::ConstraintCase::kExactlyOne:
553 case ConstraintProto::ConstraintCase::kBoolXor:
555 case ConstraintProto::ConstraintCase::kIntDiv:
557 case ConstraintProto::ConstraintCase::kIntMod:
559 case ConstraintProto::ConstraintCase::kLinMax:
561 case ConstraintProto::ConstraintCase::kIntProd:
563 case ConstraintProto::ConstraintCase::kLinear:
565 case ConstraintProto::ConstraintCase::kAllDiff:
567 case ConstraintProto::ConstraintCase::kDummyConstraint:
569 case ConstraintProto::ConstraintCase::kElement:
571 case ConstraintProto::ConstraintCase::kCircuit:
573 case ConstraintProto::ConstraintCase::kRoutes:
575 case ConstraintProto::ConstraintCase::kInverse:
577 case ConstraintProto::ConstraintCase::kReservoir:
579 case ConstraintProto::ConstraintCase::kTable:
581 case ConstraintProto::ConstraintCase::kAutomaton:
583 case ConstraintProto::ConstraintCase::kInterval:
585 case ConstraintProto::ConstraintCase::kNoOverlap:
586 AddIndices(ct.no_overlap().intervals(), &used_intervals);
588 case ConstraintProto::ConstraintCase::kNoOverlap2D:
589 AddIndices(ct.no_overlap_2d().x_intervals(), &used_intervals);
590 AddIndices(ct.no_overlap_2d().y_intervals(), &used_intervals);
592 case ConstraintProto::ConstraintCase::kCumulative:
593 AddIndices(ct.cumulative().intervals(), &used_intervals);
595 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
599 return used_intervals;
709 for (
const IntegerVariableProto& var_proto : model.variables()) {
712 for (
const ConstraintProto& ct : model.constraints()) {
713 if (!ct.enforcement_literal().empty()) {
716 switch (ct.constraint_case()) {
717 case ConstraintProto::ConstraintCase::kBoolOr:
720 case ConstraintProto::ConstraintCase::kBoolAnd:
723 case ConstraintProto::ConstraintCase::kAtMostOne:
726 case ConstraintProto::ConstraintCase::kExactlyOne:
729 case ConstraintProto::ConstraintCase::kBoolXor:
732 case ConstraintProto::ConstraintCase::kIntDiv:
734 for (
const LinearExpressionProto& expr : ct.int_div().exprs()) {
738 case ConstraintProto::ConstraintCase::kIntMod:
740 for (
const LinearExpressionProto& expr : ct.int_mod().exprs()) {
744 case ConstraintProto::ConstraintCase::kLinMax: {
746 for (
const LinearExpressionProto& expr : ct.lin_max().exprs()) {
751 case ConstraintProto::ConstraintCase::kIntProd:
753 for (
const LinearExpressionProto& expr : ct.int_prod().exprs()) {
757 case ConstraintProto::ConstraintCase::kLinear:
762 case ConstraintProto::ConstraintCase::kAllDiff:
763 for (
const LinearExpressionProto& expr : ct.all_diff().exprs()) {
767 case ConstraintProto::ConstraintCase::kDummyConstraint:
769 case ConstraintProto::ConstraintCase::kElement:
775 for (
const LinearExpressionProto& expr : ct.element().exprs()) {
779 case ConstraintProto::ConstraintCase::kCircuit:
784 case ConstraintProto::ConstraintCase::kRoutes:
789 case ConstraintProto::ConstraintCase::kInverse:
793 case ConstraintProto::ConstraintCase::kReservoir:
796 for (
const LinearExpressionProto& expr : ct.reservoir().time_exprs()) {
799 for (
const LinearExpressionProto& expr :
800 ct.reservoir().level_changes()) {
804 case ConstraintProto::ConstraintCase::kTable:
805 if (!ct.table().vars().empty()) {
808 for (
const LinearExpressionProto& expr : ct.table().exprs()) {
815 case ConstraintProto::ConstraintCase::kAutomaton:
821 if (!ct.automaton().vars().empty()) {
824 for (
const LinearExpressionProto& expr : ct.automaton().exprs()) {
829 case ConstraintProto::ConstraintCase::kInterval:
834 case ConstraintProto::ConstraintCase::kNoOverlap:
837 case ConstraintProto::ConstraintCase::kNoOverlap2D:
841 case ConstraintProto::ConstraintCase::kCumulative:
844 for (
const LinearExpressionProto& demand : ct.cumulative().demands()) {
848 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
854 if (model.has_objective()) {
860 }
else if (model.has_floating_point_objective()) {
869 if (model.has_solution_hint()) {
963 if (cp_model.has_objective())
return false;
964 const int num_vars = cp_model.variables().size();
965 for (
int v = 0; v < num_vars; ++v) {
966 if (cp_model.variables(v).domain().size() != 2)
return false;
967 if (cp_model.variables(v).domain(0) != 0)
return false;
968 if (cp_model.variables(v).domain(1) != 1)
return false;
971 for (
const ConstraintProto& ct : cp_model.constraints()) {
972 if (ct.constraint_case() == ConstraintProto::kBoolOr) {
974 }
else if (ct.constraint_case() == ConstraintProto::kBoolAnd) {
975 num_clauses += ct.bool_and().literals().size();
983 absl::StrAppend(out,
"p cnf ", num_vars,
" ", num_clauses,
"\n");
984 for (
const ConstraintProto& ct : cp_model.constraints()) {
985 if (ct.constraint_case() == ConstraintProto::kBoolOr) {
986 CHECK(ct.enforcement_literal().empty());
987 for (
const int lit : ct.bool_or().literals()) {
991 absl::StrAppend(out, value,
" ");
993 absl::StrAppend(out,
"0\n");
994 }
else if (ct.constraint_case() == ConstraintProto::kBoolAnd) {
995 CHECK(!ct.enforcement_literal().empty());
997 for (
const int lit : ct.enforcement_literal()) {
1001 absl::StrAppend(&start, -value,
" ");
1003 for (
const int lit : ct.bool_and().literals()) {
1007 absl::StrAppend(out, start, value,
" 0\n");