OR-Tools  9.2
cp_model.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 
14 #include "ortools/sat/cp_model.h"
15 
16 #include <cstdint>
17 #include <initializer_list>
18 #include <limits>
19 #include <string>
20 
21 #include "absl/strings/str_format.h"
22 #include "ortools/base/map_util.h"
27 
28 namespace operations_research {
29 namespace sat {
30 
31 BoolVar::BoolVar() : builder_(nullptr), index_(0) {}
32 
34  : builder_(builder), index_(index) {}
35 
36 BoolVar BoolVar::WithName(const std::string& name) {
37  DCHECK(builder_ != nullptr);
38  if (builder_ == nullptr) return *this;
39  builder_->MutableProto()
41  ->set_name(name);
42  return *this;
43 }
44 
45 std::string BoolVar::Name() const {
46  if (builder_ == nullptr) return "null";
47  const std::string& name =
48  builder_->Proto().variables(PositiveRef(index_)).name();
49  if (RefIsPositive(index_)) {
50  return name;
51  } else {
52  return absl::StrCat("Not(", name, ")");
53  }
54 }
55 
56 std::string BoolVar::DebugString() const {
57  if (builder_ == nullptr) return "null";
58  if (index_ < 0) {
59  return absl::StrFormat("Not(%s)", Not().DebugString());
60  } else {
61  std::string output;
62  const IntegerVariableProto& var_proto = builder_->Proto().variables(index_);
63  // Special case for constant variables without names.
64  if (var_proto.name().empty() && var_proto.domain_size() == 2 &&
65  var_proto.domain(0) == var_proto.domain(1)) {
66  output.append(var_proto.domain(0) == 0 ? "false" : "true");
67  } else {
68  if (var_proto.name().empty()) {
69  absl::StrAppendFormat(&output, "BoolVar%i(", index_);
70  } else {
71  absl::StrAppendFormat(&output, "%s(", var_proto.name());
72  }
73  if (var_proto.domain(0) == var_proto.domain(1)) {
74  output.append(var_proto.domain(0) == 0 ? "false)" : "true)");
75  } else {
76  absl::StrAppend(&output, var_proto.domain(0), ", ", var_proto.domain(1),
77  ")");
78  }
79  }
80  return output;
81  }
82 }
83 
84 BoolVar Not(BoolVar x) { return x.Not(); }
85 
86 std::ostream& operator<<(std::ostream& os, const BoolVar& var) {
87  os << var.DebugString();
88  return os;
89 }
90 
91 IntVar::IntVar() : builder_(nullptr), index_(0) {}
92 
93 IntVar::IntVar(int index, CpModelBuilder* builder)
94  : builder_(builder), index_(index) {
95  DCHECK(RefIsPositive(index_));
96 }
97 
99  if (var.builder_ == nullptr) {
100  *this = IntVar();
101  return;
102  }
103  builder_ = var.builder_;
104  index_ = builder_->GetOrCreateIntegerIndex(var.index_);
105  DCHECK(RefIsPositive(index_));
106 }
107 
109  if (builder_ != nullptr) {
110  const IntegerVariableProto& proto = builder_->Proto().variables(index_);
111  DCHECK_EQ(2, proto.domain_size());
112  DCHECK_GE(proto.domain(0), 0);
113  DCHECK_LE(proto.domain(1), 1);
114  }
115  return BoolVar(index_, builder_);
116 }
117 
118 IntVar IntVar::WithName(const std::string& name) {
119  DCHECK(builder_ != nullptr);
120  if (builder_ == nullptr) return *this;
121  builder_->MutableProto()->mutable_variables(index_)->set_name(name);
122  return *this;
123 }
124 
125 std::string IntVar::Name() const {
126  if (builder_ == nullptr) return "null";
127  return builder_->Proto().variables(index_).name();
128 }
129 
131  if (builder_ == nullptr) return Domain();
132  return ReadDomainFromProto(builder_->Proto().variables(index_));
133 }
134 
135 std::string IntVar::DebugString() const {
136  if (builder_ == nullptr) return "null";
137  return VarDebugString(builder_->Proto(), index_);
138 }
139 
140 // TODO(user): unfortunately, we need this indirection to get a DebugString()
141 // in a const way from an index. Because building an IntVar is non-const.
142 std::string VarDebugString(const CpModelProto& proto, int index) {
143  std::string output;
144 
145  // Special case for constant variables without names.
146  const IntegerVariableProto& var_proto = proto.variables(index);
147  if (var_proto.name().empty() && var_proto.domain_size() == 2 &&
148  var_proto.domain(0) == var_proto.domain(1)) {
149  absl::StrAppend(&output, var_proto.domain(0));
150  } else {
151  if (var_proto.name().empty()) {
152  absl::StrAppend(&output, "V", index, "(");
153  } else {
154  absl::StrAppend(&output, var_proto.name(), "(");
155  }
156 
157  // TODO(user): Use domain pretty print function.
158  if (var_proto.domain_size() == 2 &&
159  var_proto.domain(0) == var_proto.domain(1)) {
160  absl::StrAppend(&output, var_proto.domain(0), ")");
161  } else {
162  absl::StrAppend(&output, var_proto.domain(0), ", ", var_proto.domain(1),
163  ")");
164  }
165  }
166 
167  return output;
168 }
169 
170 std::ostream& operator<<(std::ostream& os, const IntVar& var) {
171  os << var.DebugString();
172  return os;
173 }
174 
176  DCHECK(var.builder_ != nullptr);
177  const int index = var.index_;
178  if (RefIsPositive(index)) {
179  variables_.push_back(index);
180  coefficients_.push_back(1);
181  } else {
182  // We add 1 - var instead.
183  variables_.push_back(PositiveRef(index));
184  coefficients_.push_back(-1);
185  constant_ += 1;
186  }
187 }
188 
190  DCHECK(var.builder_ != nullptr);
191  variables_.push_back(var.index_);
192  coefficients_.push_back(1);
193 }
194 
195 LinearExpr::LinearExpr(int64_t constant) { constant_ = constant; }
196 
198  LinearExpr result(expr_proto.offset());
199  for (int i = 0; i < expr_proto.vars_size(); ++i) {
200  result.variables_.push_back(expr_proto.vars(i));
201  result.coefficients_.push_back(expr_proto.coeffs(i));
202  }
203  return result;
204 }
205 
206 LinearExpr LinearExpr::Sum(absl::Span<const IntVar> vars) {
207  LinearExpr result;
208  for (const IntVar& var : vars) {
209  result += var;
210  }
211  return result;
212 }
213 
214 LinearExpr LinearExpr::Sum(absl::Span<const BoolVar> vars) {
215  LinearExpr result;
216  for (const BoolVar& var : vars) {
217  result += var;
218  }
219  return result;
220 }
221 
222 LinearExpr LinearExpr::WeightedSum(absl::Span<const IntVar> vars,
223  absl::Span<const int64_t> coeffs) {
224  CHECK_EQ(vars.size(), coeffs.size());
225  LinearExpr result;
226  for (int i = 0; i < vars.size(); ++i) {
227  result += vars[i] * coeffs[i];
228  }
229  return result;
230 }
231 
232 LinearExpr LinearExpr::WeightedSum(absl::Span<const BoolVar> vars,
233  absl::Span<const int64_t> coeffs) {
234  CHECK_EQ(vars.size(), coeffs.size());
235  LinearExpr result;
236  for (int i = 0; i < vars.size(); ++i) {
237  result += vars[i] * coeffs[i];
238  }
239  return result;
240 }
241 
243  LinearExpr result;
244  result += var * coefficient;
245  return result;
246 }
247 
249  LinearExpr result;
250  result += var * coefficient;
251  return result;
252 }
253 
255  constant_ += other.constant_;
256  variables_.insert(variables_.end(), other.variables_.begin(),
257  other.variables_.end());
258  coefficients_.insert(coefficients_.end(), other.coefficients_.begin(),
259  other.coefficients_.end());
260  return *this;
261 }
262 
264  constant_ -= other.constant_;
265  variables_.insert(variables_.end(), other.variables_.begin(),
266  other.variables_.end());
267  for (const int64_t coeff : other.coefficients_) {
268  coefficients_.push_back(-coeff);
269  }
270  return *this;
271 }
272 
274  constant_ *= factor;
275  for (int64_t& coeff : coefficients_) coeff *= factor;
276  return *this;
277 }
278 
279 std::string LinearExpr::DebugString(const CpModelProto* proto) const {
280  std::string result;
281  for (int i = 0; i < variables_.size(); ++i) {
282  const int64_t coeff = coefficients_[i];
283  const std::string var_string = proto == nullptr
284  ? absl::StrCat("V", variables_[i])
285  : VarDebugString(*proto, variables_[i]);
286  if (i == 0) {
287  if (coeff == 1) {
288  absl::StrAppend(&result, var_string);
289  } else if (coeff == -1) {
290  absl::StrAppend(&result, "-", var_string);
291  } else if (coeff != 0) {
292  absl::StrAppend(&result, coeff, " * ", var_string);
293  }
294  } else if (coeff == 1) {
295  absl::StrAppend(&result, " + ", var_string);
296  } else if (coeff > 0) {
297  absl::StrAppend(&result, " + ", coeff, " * ", var_string);
298  } else if (coeff == -1) {
299  absl::StrAppend(&result, " - ", var_string);
300  } else if (coeff < 0) {
301  absl::StrAppend(&result, " - ", -coeff, " * ", var_string);
302  }
303  }
304 
305  if (constant_ != 0) {
306  if (variables_.empty()) {
307  return absl::StrCat(constant_);
308  } else if (constant_ > 0) {
309  absl::StrAppend(&result, " + ", constant_);
310  } else {
311  absl::StrAppend(&result, " - ", -constant_);
312  }
313  }
314  return result;
315 }
316 
317 std::ostream& operator<<(std::ostream& os, const LinearExpr& e) {
318  os << e.DebugString();
319  return os;
320 }
321 
323 
325 
327 
328 DoubleLinearExpr::DoubleLinearExpr(double constant) { constant_ = constant; }
329 
330 DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const IntVar> vars) {
331  DoubleLinearExpr result;
332  for (const IntVar& var : vars) {
333  result.AddTerm(var, 1.0);
334  }
335  return result;
336 }
337 
338 DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const BoolVar> vars) {
339  DoubleLinearExpr result;
340  for (const BoolVar& var : vars) {
341  result.AddTerm(var, 1.0);
342  }
343  return result;
344 }
345 
347  absl::Span<const IntVar> vars, absl::Span<const double> coeffs) {
348  CHECK_EQ(vars.size(), coeffs.size());
349  DoubleLinearExpr result;
350  for (int i = 0; i < vars.size(); ++i) {
351  result.AddTerm(vars[i], coeffs[i]);
352  }
353  return result;
354 }
355 
357  absl::Span<const BoolVar> vars, absl::Span<const double> coeffs) {
358  CHECK_EQ(vars.size(), coeffs.size());
359  DoubleLinearExpr result;
360  for (int i = 0; i < vars.size(); ++i) {
361  result.AddTerm(vars[i], coeffs[i]);
362  }
363  return result;
364 }
365 
367  constant_ += value;
368  return *this;
369 }
370 
372  AddTerm(var, 1);
373  return *this;
374 }
375 
377  AddTerm(var, 1);
378  return *this;
379 }
380 
382  constant_ += expr.constant_;
383  variables_.insert(variables_.end(), expr.variables_.begin(),
384  expr.variables_.end());
385  coefficients_.insert(coefficients_.end(), expr.coefficients_.begin(),
386  expr.coefficients_.end());
387  return *this;
388 }
389 
391  variables_.push_back(var.index_);
392  coefficients_.push_back(coeff);
393  return *this;
394 }
395 
397  const int index = var.index_;
398  if (RefIsPositive(index)) {
399  variables_.push_back(index);
400  coefficients_.push_back(coeff);
401  } else {
402  variables_.push_back(PositiveRef(index));
403  coefficients_.push_back(-coeff);
404  constant_ += coeff;
405  }
406  return *this;
407 }
408 
410  constant_ -= value;
411  return *this;
412 }
413 
415  AddTerm(var, -1.0);
416  return *this;
417 }
418 
420  constant_ -= expr.constant_;
421  variables_.insert(variables_.end(), expr.variables_.begin(),
422  expr.variables_.end());
423  for (const double coeff : expr.coefficients()) {
424  coefficients_.push_back(-coeff);
425  }
426  return *this;
427 }
428 
430  constant_ *= coeff;
431  for (double& c : coefficients_) {
432  c *= coeff;
433  }
434  return *this;
435 }
436 
438  std::string result;
439  for (int i = 0; i < variables_.size(); ++i) {
440  const double coeff = coefficients_[i];
441  const std::string var_string = proto == nullptr
442  ? absl::StrCat("V", variables_[i])
443  : VarDebugString(*proto, variables_[i]);
444  if (i == 0) {
445  if (coeff == 1.0) {
446  absl::StrAppend(&result, var_string);
447  } else if (coeff == -1.0) {
448  absl::StrAppend(&result, "-", var_string);
449  } else if (coeff != 0.0) {
450  absl::StrAppend(&result, coeff, " * ", var_string);
451  }
452  } else if (coeff == 1.0) {
453  absl::StrAppend(&result, " + ", var_string);
454  } else if (coeff > 0.0) {
455  absl::StrAppend(&result, " + ", coeff, " * ", var_string);
456  } else if (coeff == -1.0) {
457  absl::StrAppend(&result, " - ", var_string);
458  } else if (coeff < 0.0) {
459  absl::StrAppend(&result, " - ", -coeff, " * ", var_string);
460  }
461  }
462 
463  if (constant_ != 0.0) {
464  if (variables_.empty()) {
465  return absl::StrCat(constant_);
466  } else if (constant_ > 0.0) {
467  absl::StrAppend(&result, " + ", constant_);
468  } else {
469  absl::StrAppend(&result, " - ", -constant_);
470  }
471  }
472  return result;
473 }
474 
475 std::ostream& operator<<(std::ostream& os, const DoubleLinearExpr& e) {
476  os << e.DebugString();
477  return os;
478 }
479 
481 
482 Constraint Constraint::WithName(const std::string& name) {
483  proto_->set_name(name);
484  return *this;
485 }
486 
487 const std::string& Constraint::Name() const { return proto_->name(); }
488 
489 Constraint Constraint::OnlyEnforceIf(absl::Span<const BoolVar> literals) {
490  for (const BoolVar& var : literals) {
492  }
493  return *this;
494 }
495 
498  return *this;
499 }
500 
505 }
506 
511 }
512 
513 void TableConstraint::AddTuple(absl::Span<const int64_t> tuple) {
514  CHECK_EQ(tuple.size(), proto_->table().vars_size());
515  for (const int64_t t : tuple) {
517  }
518 }
519 
520 ReservoirConstraint::ReservoirConstraint(ConstraintProto* proto,
521  CpModelBuilder* builder)
522  : Constraint(proto), builder_(builder) {}
523 
524 void ReservoirConstraint::AddEvent(LinearExpr time, int64_t level_change) {
526  builder_->LinearExprToProto(time);
527  proto_->mutable_reservoir()->add_level_changes(level_change);
529  builder_->IndexFromConstant(1));
530 }
531 
533  int64_t level_change,
534  BoolVar is_active) {
536  builder_->LinearExprToProto(time);
537  proto_->mutable_reservoir()->add_level_changes(level_change);
538  proto_->mutable_reservoir()->add_active_literals(is_active.index_);
539 }
540 
542  int64_t transition_label) {
545  proto_->mutable_automaton()->add_transition_label(transition_label);
546 }
547 
549  IntervalVar y_coordinate) {
550  proto_->mutable_no_overlap_2d()->add_x_intervals(x_coordinate.index_);
551  proto_->mutable_no_overlap_2d()->add_y_intervals(y_coordinate.index_);
552 }
553 
554 CumulativeConstraint::CumulativeConstraint(ConstraintProto* proto,
555  CpModelBuilder* builder)
556  : Constraint(proto), builder_(builder) {}
557 
561  builder_->LinearExprToProto(demand);
562 }
563 
564 IntervalVar::IntervalVar() : builder_(nullptr), index_() {}
565 
567  : builder_(builder), index_(index) {}
568 
570  DCHECK(builder_ != nullptr);
571  if (builder_ == nullptr) return *this;
572  builder_->MutableProto()->mutable_constraints(index_)->set_name(name);
573  return *this;
574 }
575 
577  DCHECK(builder_ != nullptr);
578  if (builder_ == nullptr) return LinearExpr();
579  return LinearExpr::FromProto(
580  builder_->Proto().constraints(index_).interval().start());
581 }
582 
584  DCHECK(builder_ != nullptr);
585  if (builder_ == nullptr) return LinearExpr();
586  return LinearExpr::FromProto(
587  builder_->Proto().constraints(index_).interval().size());
588 }
589 
591  DCHECK(builder_ != nullptr);
592  if (builder_ == nullptr) return LinearExpr();
593  return LinearExpr::FromProto(
594  builder_->Proto().constraints(index_).interval().end());
595 }
596 
598  DCHECK(builder_ != nullptr);
599  if (builder_ == nullptr) return BoolVar();
600  return BoolVar(builder_->Proto().constraints(index_).enforcement_literal(0),
601  builder_);
602 }
603 
604 std::string IntervalVar::Name() const {
605  if (builder_ == nullptr) return "null";
606  return builder_->Proto().constraints(index_).name();
607 }
608 
609 std::string IntervalVar::DebugString() const {
610  if (builder_ == nullptr) return "null";
611 
612  CHECK_GE(index_, 0);
613  const CpModelProto& proto = builder_->Proto();
614  const ConstraintProto& ct_proto = proto.constraints(index_);
615  std::string output;
616  if (ct_proto.name().empty()) {
617  absl::StrAppend(&output, "IntervalVar", index_, "(");
618  } else {
619  absl::StrAppend(&output, ct_proto.name(), "(");
620  }
621  absl::StrAppend(&output, StartExpr().DebugString(&proto), ", ",
622  SizeExpr().DebugString(&proto), ", ",
623  EndExpr().DebugString(&proto), ", ",
624  PresenceBoolVar().DebugString(), ")");
625  return output;
626 }
627 
628 std::ostream& operator<<(std::ostream& os, const IntervalVar& var) {
629  os << var.DebugString();
630  return os;
631 }
632 
633 void CpModelBuilder::SetName(const std::string& name) {
634  cp_model_.set_name(name);
635 }
636 
637 int CpModelBuilder::IndexFromConstant(int64_t value) {
638  if (!constant_to_index_map_.contains(value)) {
639  const int index = cp_model_.variables_size();
640  IntegerVariableProto* const var_proto = cp_model_.add_variables();
641  var_proto->add_domain(value);
642  var_proto->add_domain(value);
643  constant_to_index_map_[value] = index;
644  }
645  return constant_to_index_map_[value];
646 }
647 
648 int CpModelBuilder::GetOrCreateIntegerIndex(int index) {
649  if (index >= 0) {
650  return index;
651  }
652  if (!bool_to_integer_index_map_.contains(index)) {
653  const int var = PositiveRef(index);
654  const IntegerVariableProto& old_var = cp_model_.variables(var);
655  const int new_index = cp_model_.variables_size();
656  IntegerVariableProto* const new_var = cp_model_.add_variables();
657  new_var->add_domain(0);
658  new_var->add_domain(1);
659  if (!old_var.name().empty()) {
660  new_var->set_name(absl::StrCat("Not(", old_var.name(), ")"));
661  }
662  AddEquality(IntVar(new_index, this), BoolVar(index, this));
663  bool_to_integer_index_map_[index] = new_index;
664  return new_index;
665  }
666  return bool_to_integer_index_map_[index];
667 }
668 
670  const int index = cp_model_.variables_size();
671  IntegerVariableProto* const var_proto = cp_model_.add_variables();
672  for (const auto& interval : domain) {
673  var_proto->add_domain(interval.start);
674  var_proto->add_domain(interval.end);
675  }
676  return IntVar(index, this);
677 }
678 
680  const int index = cp_model_.variables_size();
681  IntegerVariableProto* const var_proto = cp_model_.add_variables();
682  var_proto->add_domain(0);
683  var_proto->add_domain(1);
684  return BoolVar(index, this);
685 }
686 
688  return IntVar(IndexFromConstant(value), this);
689 }
690 
692  return BoolVar(IndexFromConstant(1), this);
693 }
694 
696  return BoolVar(IndexFromConstant(0), this);
697 }
698 
700  const LinearExpr& size,
701  const LinearExpr& end) {
702  return NewOptionalIntervalVar(start, size, end, TrueVar());
703 }
704 
706  int64_t size) {
707  return NewOptionalFixedSizeIntervalVar(start, size, TrueVar());
708 }
709 
711  const LinearExpr& size,
712  const LinearExpr& end,
713  BoolVar presence) {
714  AddEquality(LinearExpr(start) + size, end).OnlyEnforceIf(presence);
715 
716  const int index = cp_model_.constraints_size();
717  ConstraintProto* const ct = cp_model_.add_constraints();
718  ct->add_enforcement_literal(presence.index_);
719  IntervalConstraintProto* const interval = ct->mutable_interval();
720  *interval->mutable_start() = LinearExprToProto(start);
721  *interval->mutable_size() = LinearExprToProto(size);
722  *interval->mutable_end() = LinearExprToProto(end);
723  return IntervalVar(index, this);
724 }
725 
727  const LinearExpr& start, int64_t size, BoolVar presence) {
728  const int index = cp_model_.constraints_size();
729  ConstraintProto* const ct = cp_model_.add_constraints();
730  ct->add_enforcement_literal(presence.index_);
731  IntervalConstraintProto* const interval = ct->mutable_interval();
732  *interval->mutable_start() = LinearExprToProto(start);
733  interval->mutable_size()->set_offset(size);
734  *interval->mutable_end() = LinearExprToProto(start);
735  interval->mutable_end()->set_offset(interval->end().offset() + size);
736  return IntervalVar(index, this);
737 }
738 
739 Constraint CpModelBuilder::AddBoolOr(absl::Span<const BoolVar> literals) {
740  ConstraintProto* const proto = cp_model_.add_constraints();
741  for (const BoolVar& lit : literals) {
742  proto->mutable_bool_or()->add_literals(lit.index_);
743  }
744  return Constraint(proto);
745 }
746 
747 Constraint CpModelBuilder::AddAtLeastOne(absl::Span<const BoolVar> literals) {
748  return AddBoolOr(literals);
749 }
750 
751 Constraint CpModelBuilder::AddAtMostOne(absl::Span<const BoolVar> literals) {
752  ConstraintProto* const proto = cp_model_.add_constraints();
753  for (const BoolVar& lit : literals) {
754  proto->mutable_at_most_one()->add_literals(lit.index_);
755  }
756  return Constraint(proto);
757 }
758 
759 Constraint CpModelBuilder::AddExactlyOne(absl::Span<const BoolVar> literals) {
760  ConstraintProto* const proto = cp_model_.add_constraints();
761  for (const BoolVar& lit : literals) {
762  proto->mutable_exactly_one()->add_literals(lit.index_);
763  }
764  return Constraint(proto);
765 }
766 
767 Constraint CpModelBuilder::AddBoolAnd(absl::Span<const BoolVar> literals) {
768  ConstraintProto* const proto = cp_model_.add_constraints();
769  for (const BoolVar& lit : literals) {
770  proto->mutable_bool_and()->add_literals(lit.index_);
771  }
772  return Constraint(proto);
773 }
774 
775 Constraint CpModelBuilder::AddBoolXor(absl::Span<const BoolVar> literals) {
776  ConstraintProto* const proto = cp_model_.add_constraints();
777  for (const BoolVar& lit : literals) {
778  proto->mutable_bool_xor()->add_literals(lit.index_);
779  }
780  return Constraint(proto);
781 }
782 
783 void CpModelBuilder::FillLinearTerms(const LinearExpr& left,
784  const LinearExpr& right,
786  for (const int x : left.variables()) {
787  proto->add_vars(x);
788  }
789  for (const int64_t coeff : left.coefficients()) {
790  proto->add_coeffs(coeff);
791  }
792  for (const int x : right.variables()) {
793  proto->add_vars(x);
794  }
795  for (const int64_t coeff : right.coefficients()) {
796  proto->add_coeffs(-coeff);
797  }
798 }
799 
801  const LinearExpr& right) {
802  ConstraintProto* const proto = cp_model_.add_constraints();
803  FillLinearTerms(left, right, proto->mutable_linear());
804  const int64_t rhs = right.constant() - left.constant();
805  proto->mutable_linear()->add_domain(rhs);
806  proto->mutable_linear()->add_domain(rhs);
807  return Constraint(proto);
808 }
809 
811  const LinearExpr& right) {
812  ConstraintProto* const proto = cp_model_.add_constraints();
813  FillLinearTerms(left, right, proto->mutable_linear());
814  const int64_t rhs = right.constant() - left.constant();
815  proto->mutable_linear()->add_domain(rhs);
816  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
817  return Constraint(proto);
818 }
819 
821  const LinearExpr& right) {
822  ConstraintProto* const proto = cp_model_.add_constraints();
823  FillLinearTerms(left, right, proto->mutable_linear());
824  const int64_t rhs = right.constant() - left.constant();
825  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
826  proto->mutable_linear()->add_domain(rhs);
827  return Constraint(proto);
828 }
829 
831  const LinearExpr& right) {
832  ConstraintProto* const proto = cp_model_.add_constraints();
833  FillLinearTerms(left, right, proto->mutable_linear());
834  const int64_t rhs = right.constant() - left.constant();
835  proto->mutable_linear()->add_domain(rhs + 1);
836  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
837  return Constraint(proto);
838 }
839 
841  const LinearExpr& right) {
842  ConstraintProto* const proto = cp_model_.add_constraints();
843  FillLinearTerms(left, right, proto->mutable_linear());
844  const int64_t rhs = right.constant() - left.constant();
845  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
846  proto->mutable_linear()->add_domain(rhs - 1);
847  return Constraint(proto);
848 }
849 
851  const Domain& domain) {
852  ConstraintProto* const proto = cp_model_.add_constraints();
853  for (const int x : expr.variables()) {
854  proto->mutable_linear()->add_vars(x);
855  }
856  for (const int64_t coeff : expr.coefficients()) {
857  proto->mutable_linear()->add_coeffs(coeff);
858  }
859  const int64_t cst = expr.constant();
860  for (const auto& i : domain) {
861  proto->mutable_linear()->add_domain(i.start - cst);
862  proto->mutable_linear()->add_domain(i.end - cst);
863  }
864  return Constraint(proto);
865 }
866 
868  const LinearExpr& right) {
869  ConstraintProto* const proto = cp_model_.add_constraints();
870  FillLinearTerms(left, right, proto->mutable_linear());
871  const int64_t rhs = right.constant() - left.constant();
872  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
873  proto->mutable_linear()->add_domain(rhs - 1);
874  proto->mutable_linear()->add_domain(rhs + 1);
875  proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
876  return Constraint(proto);
877 }
878 
879 Constraint CpModelBuilder::AddAllDifferent(absl::Span<const IntVar> vars) {
880  ConstraintProto* const proto = cp_model_.add_constraints();
881  for (const IntVar& var : vars) {
882  auto* expr = proto->mutable_all_diff()->add_exprs();
883  expr->add_vars(var.index_);
884  expr->add_coeffs(1);
885  }
886  return Constraint(proto);
887 }
888 
889 Constraint CpModelBuilder::AddAllDifferent(absl::Span<const LinearExpr> exprs) {
890  ConstraintProto* const proto = cp_model_.add_constraints();
891  for (const LinearExpr& expr : exprs) {
892  *proto->mutable_all_diff()->add_exprs() = LinearExprToProto(expr);
893  }
894  return Constraint(proto);
895 }
896 
898  std::initializer_list<LinearExpr> exprs) {
899  ConstraintProto* const proto = cp_model_.add_constraints();
900  for (const LinearExpr& expr : exprs) {
901  *proto->mutable_all_diff()->add_exprs() = LinearExprToProto(expr);
902  }
903  return Constraint(proto);
904 }
905 
907  IntVar index, absl::Span<const IntVar> variables, IntVar target) {
908  ConstraintProto* const proto = cp_model_.add_constraints();
909  proto->mutable_element()->set_index(index.index_);
910  proto->mutable_element()->set_target(target.index_);
911  for (const IntVar& var : variables) {
912  proto->mutable_element()->add_vars(var.index_);
913  }
914  return Constraint(proto);
915 }
916 
918  absl::Span<const int64_t> values,
919  IntVar target) {
920  ConstraintProto* const proto = cp_model_.add_constraints();
921  proto->mutable_element()->set_index(index.index_);
922  proto->mutable_element()->set_target(target.index_);
923  for (int64_t value : values) {
924  proto->mutable_element()->add_vars(IndexFromConstant(value));
925  }
926  return Constraint(proto);
927 }
928 
930  return CircuitConstraint(cp_model_.add_constraints());
931 }
932 
934  return MultipleCircuitConstraint(cp_model_.add_constraints());
935 }
936 
938  absl::Span<const IntVar> vars) {
939  ConstraintProto* const proto = cp_model_.add_constraints();
940  for (const IntVar& var : vars) {
941  proto->mutable_table()->add_vars(var.index_);
942  }
943  return TableConstraint(proto);
944 }
945 
947  absl::Span<const IntVar> vars) {
948  ConstraintProto* const proto = cp_model_.add_constraints();
949  for (const IntVar& var : vars) {
950  proto->mutable_table()->add_vars(var.index_);
951  }
952  proto->mutable_table()->set_negated(true);
953  return TableConstraint(proto);
954 }
955 
957  absl::Span<const IntVar> variables,
958  absl::Span<const IntVar> inverse_variables) {
959  ConstraintProto* const proto = cp_model_.add_constraints();
960  for (const IntVar& var : variables) {
961  proto->mutable_inverse()->add_f_direct(var.index_);
962  }
963  for (const IntVar& var : inverse_variables) {
964  proto->mutable_inverse()->add_f_inverse(var.index_);
965  }
966  return Constraint(proto);
967 }
968 
970  int64_t max_level) {
971  ConstraintProto* const proto = cp_model_.add_constraints();
972  proto->mutable_reservoir()->set_min_level(min_level);
973  proto->mutable_reservoir()->set_max_level(max_level);
974  return ReservoirConstraint(proto, this);
975 }
976 
978  absl::Span<const IntVar> transition_variables, int starting_state,
979  absl::Span<const int> final_states) {
980  ConstraintProto* const proto = cp_model_.add_constraints();
981  for (const IntVar& var : transition_variables) {
982  proto->mutable_automaton()->add_vars(var.index_);
983  }
984  proto->mutable_automaton()->set_starting_state(starting_state);
985  for (const int final_state : final_states) {
986  proto->mutable_automaton()->add_final_states(final_state);
987  }
988  return AutomatonConstraint(proto);
989 }
990 
991 LinearExpressionProto CpModelBuilder::LinearExprToProto(const LinearExpr& expr,
992  bool negate) {
993  LinearExpressionProto expr_proto;
994  for (const int var : expr.variables()) {
995  expr_proto.add_vars(var);
996  }
997  const int64_t mult = negate ? -1 : 1;
998  for (const int64_t coeff : expr.coefficients()) {
999  expr_proto.add_coeffs(coeff * mult);
1000  }
1001  expr_proto.set_offset(expr.constant() * mult);
1002  return expr_proto;
1003 }
1004 
1006  absl::Span<const IntVar> vars) {
1007  ConstraintProto* ct = cp_model_.add_constraints();
1008  *ct->mutable_lin_max()->mutable_target() =
1009  LinearExprToProto(target, /*negate=*/true);
1010  for (const IntVar& var : vars) {
1011  *ct->mutable_lin_max()->add_exprs() =
1012  LinearExprToProto(var, /*negate=*/true);
1013  }
1014  return Constraint(ct);
1015 }
1016 
1018  absl::Span<const LinearExpr> exprs) {
1019  ConstraintProto* ct = cp_model_.add_constraints();
1020  *ct->mutable_lin_max()->mutable_target() =
1021  LinearExprToProto(target, /*negate=*/true);
1022  for (const LinearExpr& expr : exprs) {
1023  *ct->mutable_lin_max()->add_exprs() =
1024  LinearExprToProto(expr, /*negate=*/true);
1025  }
1026  return Constraint(ct);
1027 }
1028 
1030  const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1031  ConstraintProto* ct = cp_model_.add_constraints();
1032  *ct->mutable_lin_max()->mutable_target() =
1033  LinearExprToProto(target, /*negate=*/true);
1034  for (const LinearExpr& expr : exprs) {
1035  *ct->mutable_lin_max()->add_exprs() =
1036  LinearExprToProto(expr, /*negate=*/true);
1037  }
1038  return Constraint(ct);
1039 }
1040 
1042  absl::Span<const IntVar> vars) {
1043  ConstraintProto* ct = cp_model_.add_constraints();
1044  *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1045  for (const IntVar& var : vars) {
1046  *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(var);
1047  }
1048  return Constraint(ct);
1049 }
1050 
1052  absl::Span<const LinearExpr> exprs) {
1053  ConstraintProto* ct = cp_model_.add_constraints();
1054  *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1055  for (const LinearExpr& expr : exprs) {
1056  *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1057  }
1058  return Constraint(ct);
1059 }
1060 
1062  const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1063  ConstraintProto* ct = cp_model_.add_constraints();
1064  *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1065  for (const LinearExpr& expr : exprs) {
1066  *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1067  }
1068  return Constraint(ct);
1069 }
1070 
1072  const LinearExpr& numerator,
1073  const LinearExpr& denominator) {
1074  ConstraintProto* const proto = cp_model_.add_constraints();
1075  *proto->mutable_int_div()->mutable_target() = LinearExprToProto(target);
1076  *proto->mutable_int_div()->add_exprs() = LinearExprToProto(numerator);
1077  *proto->mutable_int_div()->add_exprs() = LinearExprToProto(denominator);
1078  return Constraint(proto);
1079 }
1080 
1082  const LinearExpr& expr) {
1083  ConstraintProto* const proto = cp_model_.add_constraints();
1084  *proto->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1085  *proto->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1086  *proto->mutable_lin_max()->add_exprs() =
1087  LinearExprToProto(expr, /*negate=*/true);
1088  return Constraint(proto);
1089 }
1090 
1092  const LinearExpr& var,
1093  const LinearExpr& mod) {
1094  ConstraintProto* const proto = cp_model_.add_constraints();
1095  *proto->mutable_int_mod()->mutable_target() = LinearExprToProto(target);
1096  *proto->mutable_int_mod()->add_exprs() = LinearExprToProto(var);
1097  *proto->mutable_int_mod()->add_exprs() = LinearExprToProto(mod);
1098  return Constraint(proto);
1099 }
1100 
1102  const LinearExpr& target, absl::Span<const IntVar> vars) {
1103  ConstraintProto* const proto = cp_model_.add_constraints();
1104  *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1105  for (const IntVar& var : vars) {
1106  *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(var);
1107  }
1108  return Constraint(proto);
1109 }
1110 
1112  const LinearExpr& target, absl::Span<const LinearExpr> exprs) {
1113  ConstraintProto* const proto = cp_model_.add_constraints();
1114  *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1115  for (const LinearExpr& expr : exprs) {
1116  *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(expr);
1117  }
1118  return Constraint(proto);
1119 }
1120 
1122  const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1123  ConstraintProto* const proto = cp_model_.add_constraints();
1124  *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1125  for (const LinearExpr& expr : exprs) {
1126  *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(expr);
1127  }
1128  return Constraint(proto);
1129 }
1131  const LinearExpr& left,
1132  const LinearExpr& right) {
1133  ConstraintProto* const proto = cp_model_.add_constraints();
1134  *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1135  *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(left);
1136  *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(right);
1137 
1138  return Constraint(proto);
1139 }
1140 
1141 Constraint CpModelBuilder::AddNoOverlap(absl::Span<const IntervalVar> vars) {
1142  ConstraintProto* const proto = cp_model_.add_constraints();
1143  for (const IntervalVar& var : vars) {
1144  proto->mutable_no_overlap()->add_intervals(var.index_);
1145  }
1146  return Constraint(proto);
1147 }
1148 
1150  return NoOverlap2DConstraint(cp_model_.add_constraints());
1151 }
1152 
1154  ConstraintProto* const proto = cp_model_.add_constraints();
1155  *proto->mutable_cumulative()->mutable_capacity() =
1156  LinearExprToProto(capacity);
1157  return CumulativeConstraint(proto, this);
1158 }
1159 
1161  cp_model_.clear_objective();
1162  cp_model_.clear_floating_point_objective();
1163  for (const int x : expr.variables()) {
1164  cp_model_.mutable_objective()->add_vars(x);
1165  }
1166  for (const int64_t coeff : expr.coefficients()) {
1167  cp_model_.mutable_objective()->add_coeffs(coeff);
1168  }
1169  cp_model_.mutable_objective()->set_offset(expr.constant());
1170 }
1171 
1173  cp_model_.clear_objective();
1174  cp_model_.clear_floating_point_objective();
1175  for (const int x : expr.variables()) {
1176  cp_model_.mutable_objective()->add_vars(x);
1177  }
1178  for (const int64_t coeff : expr.coefficients()) {
1179  cp_model_.mutable_objective()->add_coeffs(-coeff);
1180  }
1181  cp_model_.mutable_objective()->set_offset(-expr.constant());
1182  cp_model_.mutable_objective()->set_scaling_factor(-1.0);
1183 }
1184 
1186  cp_model_.clear_objective();
1187  cp_model_.clear_floating_point_objective();
1188  for (int i = 0; i < expr.variables().size(); ++i) {
1189  cp_model_.mutable_floating_point_objective()->add_vars(expr.variables()[i]);
1191  expr.coefficients()[i]);
1192  }
1194  cp_model_.mutable_floating_point_objective()->set_maximize(false);
1195 }
1196 
1198  cp_model_.clear_objective();
1199  cp_model_.clear_floating_point_objective();
1200  for (int i = 0; i < expr.variables().size(); ++i) {
1201  cp_model_.mutable_floating_point_objective()->add_vars(expr.variables()[i]);
1203  expr.coefficients()[i]);
1204  }
1207 }
1208 
1210  absl::Span<const IntVar> variables,
1213  DecisionStrategyProto* const proto = cp_model_.add_search_strategy();
1214  for (const IntVar& var : variables) {
1215  proto->add_variables(var.index_);
1216  }
1217  proto->set_variable_selection_strategy(var_strategy);
1218  proto->set_domain_reduction_strategy(domain_strategy);
1219 }
1220 
1222  absl::Span<const BoolVar> variables,
1225  DecisionStrategyProto* const proto = cp_model_.add_search_strategy();
1226  for (const BoolVar& var : variables) {
1227  proto->add_variables(var.index_);
1228  }
1229  proto->set_variable_selection_strategy(var_strategy);
1230  proto->set_domain_reduction_strategy(domain_strategy);
1231 }
1232 
1234  cp_model_.mutable_solution_hint()->add_vars(var.index_);
1235  cp_model_.mutable_solution_hint()->add_values(value);
1236 }
1237 
1239  if (var.index_ >= 0) {
1240  cp_model_.mutable_solution_hint()->add_vars(var.index_);
1241  cp_model_.mutable_solution_hint()->add_values(value);
1242  } else {
1243  cp_model_.mutable_solution_hint()->add_vars(PositiveRef(var.index_));
1244  cp_model_.mutable_solution_hint()->add_values(!value);
1245  }
1246 }
1247 
1249  cp_model_.mutable_solution_hint()->Clear();
1250 }
1251 
1253  cp_model_.mutable_assumptions()->Add(lit.index_);
1254 }
1255 
1256 void CpModelBuilder::AddAssumptions(absl::Span<const BoolVar> literals) {
1257  for (const BoolVar& lit : literals) {
1258  cp_model_.mutable_assumptions()->Add(lit.index_);
1259  }
1260 }
1261 
1263  cp_model_.mutable_assumptions()->Clear();
1264 }
1265 
1267  cp_model_ = model_proto;
1268  // Rebuild constant to index map.
1269  constant_to_index_map_.clear();
1270  for (int i = 0; i < cp_model_.variables_size(); ++i) {
1271  const IntegerVariableProto& var = cp_model_.variables(i);
1272  if (var.domain_size() == 2 && var.domain(0) == var.domain(1)) {
1273  constant_to_index_map_[var.domain(0)] = i;
1274  }
1275  }
1276  // This one would be more complicated to rebuild. Let's just clear it.
1277  bool_to_integer_index_map_.clear();
1278 }
1279 
1281  CHECK_GE(index, 0);
1282  CHECK_LT(index, cp_model_.variables_size());
1283  const IntegerVariableProto& proto = cp_model_.variables(index);
1284  CHECK_EQ(2, proto.domain_size())
1285  << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1286  "is not Boolean";
1287  CHECK_GE(0, proto.domain(0))
1288  << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1289  "is not Boolean";
1290  CHECK_LE(1, proto.domain(1))
1291  << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1292  "is not Boolean";
1293  return BoolVar(index, this);
1294 }
1295 
1297  CHECK_GE(index, 0);
1298  CHECK_LT(index, cp_model_.variables_size());
1299  return IntVar(index, this);
1300 }
1301 
1303  CHECK_GE(index, 0);
1304  CHECK_LT(index, cp_model_.constraints_size());
1305  const ConstraintProto& ct = cp_model_.constraints(index);
1306  CHECK_EQ(ct.constraint_case(), ConstraintProto::kInterval)
1307  << "CpModelBuilder::GetIntervalVarFromProtoIndex: the referenced "
1308  "object is not an interval variable";
1309  return IntervalVar(index, this);
1310 }
1311 
1313  const LinearExpr& expr) {
1314  int64_t result = expr.constant();
1315  const std::vector<int>& variables = expr.variables();
1316  const std::vector<int64_t>& coefficients = expr.coefficients();
1317  for (int i = 0; i < variables.size(); ++i) {
1318  result += r.solution(variables[i]) * coefficients[i];
1319  }
1320  return result;
1321 }
1322 
1324  const int ref = x.index_;
1325  if (RefIsPositive(ref)) {
1326  return r.solution(ref) == 1;
1327  } else {
1328  return r.solution(PositiveRef(ref)) == 0;
1329  }
1330 }
1331 
1332 } // namespace sat
1333 } // namespace operations_research
int64_t head
void AddArc(int tail, int head, BoolVar literal)
Add an arc to the circuit.
Definition: cp_model.cc:507
BoolVar FalseVar()
Creates an always false Boolean variable.
Definition: cp_model.cc:695
IntervalVar NewOptionalFixedSizeIntervalVar(const LinearExpr &start, int64_t size, BoolVar presence)
Creates an optional interval variable with a fixed size.
Definition: cp_model.cc:726
const ::operations_research::sat::TableConstraintProto & table() const
::operations_research::sat::LinearExpressionProto * add_demands()
Definition: cp_model.pb.h:8332
Specialized reservoir constraint.
Definition: cp_model.h:630
LinearExpr EndExpr() const
Returns the end linear expression.
Definition: cp_model.cc:590
IntervalVar()
A default constructed IntervalVar can be used to mean not defined yet.
Definition: cp_model.cc:564
BoolVar TrueVar()
Creates an always true Boolean variable.
Definition: cp_model.cc:691
Constraint AddMinEquality(const LinearExpr &target, absl::Span< const IntVar > vars)
Adds target == min(vars).
Definition: cp_model.cc:1005
const CpModelProto & Proto() const
Definition: cp_model.h:1061
int64_t min
Definition: alldiff_cst.cc:139
void AddAssumption(BoolVar lit)
Adds a literal to the model as assumptions.
Definition: cp_model.cc:1252
int64_t SolutionIntegerValue(const CpSolverResponse &r, const LinearExpr &expr)
Evaluates the value of an linear expression in a solver response.
Definition: cp_model.cc:1312
std::string DebugString() const
Definition: cp_model.cc:56
static LinearExpr Term(IntVar var, int64_t coefficient)
Constructs var * coefficient.
Definition: cp_model.cc:242
A dedicated container for linear expressions with double coefficients.
Definition: cp_model.h:349
CircuitConstraint AddCircuitConstraint()
Adds a circuit constraint.
Definition: cp_model.cc:929
Constraint AddGreaterThan(const LinearExpr &left, const LinearExpr &right)
Adds left > right.
Definition: cp_model.cc:830
Specialized no_overlap2D constraint.
Definition: cp_model.h:680
#define CHECK_GE(val1, val2)
Definition: base/logging.h:706
BoolVar Not() const
Returns the logical negation of the current Boolean variable.
Definition: cp_model.h:88
int64_t constant() const
Returns the constant term.
Definition: cp_model.h:296
void AddDecisionStrategy(absl::Span< const IntVar > variables, DecisionStrategyProto::VariableSelectionStrategy var_strategy, DecisionStrategyProto::DomainReductionStrategy domain_strategy)
Adds a decision strategy on a list of integer variables.
Definition: cp_model.cc:1209
const ::operations_research::sat::LinearExpressionProto & start() const
Definition: cp_model.pb.h:7741
Constraint AddAllDifferent(absl::Span< const IntVar > vars)
This constraint forces all variables to have different values.
Definition: cp_model.cc:879
Constraint AddEquality(const LinearExpr &left, const LinearExpr &right)
Adds left == right.
Definition: cp_model.cc:800
::operations_research::sat::CircuitConstraintProto * mutable_circuit()
TableConstraint AddAllowedAssignments(absl::Span< const IntVar > vars)
Adds an allowed assignments constraint.
Definition: cp_model.cc:937
const ::operations_research::sat::LinearExpressionProto & size() const
Definition: cp_model.pb.h:7921
const std::string name
ReservoirConstraint AddReservoirConstraint(int64_t min_level, int64_t max_level)
Adds a reservoir constraint with optional refill/emptying events.
Definition: cp_model.cc:969
const std::vector< double > & coefficients() const
Returns the vector of coefficients.
Definition: cp_model.h:407
void AddTuple(absl::Span< const int64_t > tuple)
Adds a tuple of possible values to the constraint.
Definition: cp_model.cc:513
IntervalVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:569
LinearExpr & operator+=(const LinearExpr &other)
Definition: cp_model.cc:254
::operations_research::sat::AutomatonConstraintProto * mutable_automaton()
::operations_research::sat::TableConstraintProto * mutable_table()
int32_t enforcement_literal(int index) const
Definition: cp_model.pb.h:9472
Constraint AddBoolOr(absl::Span< const BoolVar > literals)
Adds the constraint that at least one of the literals must be true.
Definition: cp_model.cc:739
IntervalVar NewFixedSizeIntervalVar(const LinearExpr &start, int64_t size)
Creates an interval variable with a fixed size.
Definition: cp_model.cc:705
Constraint AddMultiplicationEquality(const LinearExpr &target, absl::Span< const LinearExpr > exprs)
Adds target == prod(exprs).
Definition: cp_model.cc:1111
std::string Name() const
Returns the name of the variable (or the empty string if not set).
Definition: cp_model.cc:125
std::string VarDebugString(const CpModelProto &proto, int index)
Definition: cp_model.cc:142
BoolVar GetBoolVarFromProtoIndex(int index)
Returns the Boolean variable from its index in the proto.
Definition: cp_model.cc:1280
AutomatonConstraint AddAutomaton(absl::Span< const IntVar > transition_variables, int starting_state, absl::Span< const int > final_states)
An automaton constraint.
Definition: cp_model.cc:977
::operations_research::sat::CumulativeConstraintProto * mutable_cumulative()
Specialized circuit constraint.
Definition: cp_model.h:567
Constraint AddBoolXor(absl::Span< const BoolVar > literals)
Adds the constraint that an odd number of literals is true.
Definition: cp_model.cc:775
::operations_research::Domain Domain() const
Definition: cp_model.cc:130
::operations_research::sat::NoOverlap2DConstraintProto * mutable_no_overlap_2d()
Specialized cumulative constraint.
Definition: cp_model.h:700
Specialized assignment constraint.
Definition: cp_model.h:613
int64_t coefficient
void AddEvent(LinearExpr time, int64_t level_change)
Adds a mandatory event.
Definition: cp_model.cc:524
An integer variable.
Definition: cp_model.h:140
::operations_research::sat::IntegerVariableProto * add_variables()
int64_t tail
void Minimize(const LinearExpr &expr)
Adds a linear minimization objective.
Definition: cp_model.cc:1160
IntVar()
A default constructed IntVar can be used to mean not defined yet.
Definition: cp_model.cc:91
void AddDemand(IntervalVar interval, LinearExpr demand)
Adds a pair (interval, demand) to the constraint.
Definition: cp_model.cc:558
const std::vector< int64_t > & coefficients() const
Returns the vector of coefficients.
Definition: cp_model.h:290
DoubleLinearExpr & operator *=(double coeff)
Multiply the linear expression by a constant.
Definition: cp_model.cc:429
CumulativeConstraint AddCumulative(LinearExpr capacity)
The cumulative constraint.
Definition: cp_model.cc:1153
const std::string & name() const
Definition: cp_model.pb.h:9412
#define CHECK_LT(val1, val2)
Definition: base/logging.h:705
IntVar NewConstant(int64_t value)
Creates a constant variable.
Definition: cp_model.cc:687
void Maximize(const LinearExpr &expr)
Adds a linear maximization objective.
Definition: cp_model.cc:1172
::operations_research::sat::RoutesConstraintProto * mutable_routes()
IntVar GetIntVarFromProtoIndex(int index)
Returns the integer variable from its index in the proto.
Definition: cp_model.cc:1296
IntervalVar NewIntervalVar(const LinearExpr &start, const LinearExpr &size, const LinearExpr &end)
Creates an interval variable from 3 affine expressions.
Definition: cp_model.cc:699
Constraint AddNotEqual(const LinearExpr &left, const LinearExpr &right)
Adds left != right.
Definition: cp_model.cc:867
void SetName(const std::string &name)
Sets the name of the model.
Definition: cp_model.cc:633
void ClearAssumptions()
Remove all assumptions from the model.
Definition: cp_model.cc:1262
int64_t max
Definition: alldiff_cst.cc:140
A Boolean variable.
Definition: cp_model.h:72
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
CpModelProto proto
Constraint AddInverseConstraint(absl::Span< const IntVar > variables, absl::Span< const IntVar > inverse_variables)
An inverse constraint.
Definition: cp_model.cc:956
BoolVar ToBoolVar() const
Cast IntVar -> BoolVar.
Definition: cp_model.cc:108
std::string Name() const
Returns the name of the variable.
Definition: cp_model.cc:45
MultipleCircuitConstraint AddMultipleCircuitConstraint()
Adds a multiple circuit constraint, aka the "VRP" (Vehicle Routing Problem) constraint.
Definition: cp_model.cc:933
void set_name(ArgT0 &&arg0, ArgT... args)
Constraint AddModuloEquality(const LinearExpr &target, const LinearExpr &var, const LinearExpr &mod)
Adds target = var % mod.
Definition: cp_model.cc:1091
Constraint AddExactlyOne(absl::Span< const BoolVar > literals)
Exactly one literal is true. Sum literals == 1.
Definition: cp_model.cc:759
BoolVar()
A default constructed BoolVar can be used to mean not defined yet.
Definition: cp_model.cc:31
BoolVar PresenceBoolVar() const
Returns a BoolVar indicating the presence of this interval.
Definition: cp_model.cc:597
DoubleLinearExpr & AddTerm(IntVar var, double coeff)
Adds a term (var * coeff) to the linear expression.
Definition: cp_model.cc:390
Constraint AddAtMostOne(absl::Span< const BoolVar > literals)
At most one literal is true. Sum literals <= 1.
Definition: cp_model.cc:751
#define CHECK_LE(val1, val2)
Definition: base/logging.h:704
const ::operations_research::sat::ConstraintProto & constraints(int index) const
int64_t demand
Definition: resource.cc:125
std::string DebugString(const CpModelProto *proto=nullptr) const
Debug string. See the documentation for LinearExpr::DebugString().
Definition: cp_model.cc:437
::operations_research::sat::ConstraintProto * add_constraints()
Constraint AddDivisionEquality(const LinearExpr &target, const LinearExpr &numerator, const LinearExpr &denominator)
Adds target = num / denom (integer division rounded towards 0).
Definition: cp_model.cc:1071
bool SolutionBooleanValue(const CpSolverResponse &r, BoolVar x)
Evaluates the value of a Boolean literal in a solver response.
Definition: cp_model.cc:1323
Constraint AddElement(IntVar index, absl::Span< const int64_t > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: cp_model.cc:917
IntervalVar GetIntervalVarFromProtoIndex(int index)
Returns the interval variable from its index in the proto.
Definition: cp_model.cc:1302
const std::string & Name() const
Returns the name of the constraint (or the empty string if not set).
Definition: cp_model.cc:487
std::string DebugString() const
Returns a debug string.
Definition: cp_model.cc:609
BoolVar Not(BoolVar x)
A convenient wrapper so we can write Not(x) instead of x.Not() which is sometimes clearer.
Definition: cp_model.cc:84
int64_t capacity
int index
Definition: pack.cc:509
IntVar NewIntVar(const Domain &domain)
Creates an integer variable with the given domain.
Definition: cp_model.cc:669
::operations_research::sat::FloatObjectiveProto * mutable_floating_point_objective()
::operations_research::sat::LinearExpressionProto * add_time_exprs()
Definition: cp_model.pb.h:8416
Constraint AddAtLeastOne(absl::Span< const BoolVar > literals)
Same as AddBoolOr. Sum literals >= 1.
Definition: cp_model.cc:747
static LinearExpr FromProto(const LinearExpressionProto &proto)
Constructs a linear expr from its proto representation.
Definition: cp_model.cc:197
::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > * mutable_assumptions()
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:894
A dedicated container for linear expressions.
Definition: cp_model.h:239
Constraint AddAbsEquality(const LinearExpr &target, const LinearExpr &expr)
Adds target == abs(expr).
Definition: cp_model.cc:1081
LinearExpr()=default
Creates an empty linear expression with value zero.
Constraint OnlyEnforceIf(absl::Span< const BoolVar > literals)
The constraint will be enforced iff all literals listed here are true.
Definition: cp_model.cc:489
static DoubleLinearExpr Sum(absl::Span< const IntVar > vars)
Constructs the sum of a list of variables.
Definition: cp_model.cc:330
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:702
static LinearExpr Sum(absl::Span< const IntVar > vars)
Constructs the sum of a list of variables.
Definition: cp_model.cc:206
const ::operations_research::sat::LinearExpressionProto & end() const
Definition: cp_model.pb.h:7831
void AddAssumptions(absl::Span< const BoolVar > literals)
Adds multiple literals to the model as assumptions.
Definition: cp_model.cc:1256
Constraint(ConstraintProto *proto)
Definition: cp_model.cc:480
Constraint AddBoolAnd(absl::Span< const BoolVar > literals)
Adds the constraint that all literals must be true.
Definition: cp_model.cc:767
::operations_research::sat::DecisionStrategyProto * add_search_strategy()
void AddOptionalEvent(LinearExpr time, int64_t level_change, BoolVar is_active)
Adds an optional event.
Definition: cp_model.cc:532
::operations_research::sat::ConstraintProto * mutable_constraints(int index)
CpModelProto const * model_proto
void AddArc(int tail, int head, BoolVar literal)
Add an arc to the circuit.
Definition: cp_model.cc:501
void ClearHints()
Removes all hints.
Definition: cp_model.cc:1248
#define DCHECK(condition)
Definition: base/logging.h:889
void set_name(ArgT0 &&arg0, ArgT... args)
We call domain any subset of Int64 = [kint64min, kint64max].
const std::vector< int > & variables() const
Returns the vector of variable indices.
Definition: cp_model.h:287
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
Specialized automaton constraint.
Definition: cp_model.h:663
LinearExpr & operator *=(int64_t factor)
Definition: cp_model.cc:273
static LinearExpr WeightedSum(absl::Span< const IntVar > vars, absl::Span< const int64_t > coeffs)
Constructs the scalar product of variables and coefficients.
Definition: cp_model.cc:222
Constraint AddGreaterOrEqual(const LinearExpr &left, const LinearExpr &right)
Adds left >= right.
Definition: cp_model.cc:810
Constraint AddVariableElement(IntVar index, absl::Span< const IntVar > variables, IntVar target)
Adds the element constraint: variables[index] == target.
Definition: cp_model.cc:906
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:890
double constant() const
Returns the constant term.
Definition: cp_model.h:413
BoolVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:36
DoubleLinearExpr & operator+=(double value)
Adds a constant value to the linear expression.
Definition: cp_model.cc:366
Constraint AddLessThan(const LinearExpr &left, const LinearExpr &right)
Adds left < right.
Definition: cp_model.cc:840
DoubleLinearExpr & operator-=(double value)
Adds a constant value to the linear expression.
Definition: cp_model.cc:409
void set_name(ArgT0 &&arg0, ArgT... args)
IntVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:118
BoolVar NewBoolVar()
Creates a Boolean variable.
Definition: cp_model.cc:679
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:892
Constraint AddNoOverlap(absl::Span< const IntervalVar > vars)
Adds a no-overlap constraint that ensures that all present intervals do not overlap in time.
Definition: cp_model.cc:1141
Constraint WithName(const std::string &name)
Sets the name of the constraint.
Definition: cp_model.cc:482
std::string DebugString() const
Definition: cp_model.cc:135
void AddRectangle(IntervalVar x_coordinate, IntervalVar y_coordinate)
Adds a rectangle (parallel to the axis) to the constraint.
Definition: cp_model.cc:548
NoOverlap2DConstraint AddNoOverlap2D()
The no_overlap_2d constraint prevents a set of boxes from overlapping.
Definition: cp_model.cc:1149
Collection of objects used to extend the Constraint Solver library.
void AddTransition(int tail, int head, int64_t transition_label)
Adds a transitions to the automaton.
Definition: cp_model.cc:541
TableConstraint AddForbiddenAssignments(absl::Span< const IntVar > vars)
Adds an forbidden assignments constraint.
Definition: cp_model.cc:946
::operations_research::sat::CpObjectiveProto * mutable_objective()
int64_t time
Definition: resource.cc:1691
const ::operations_research::sat::IntervalConstraintProto & interval() const
This file implements a wrapper around the CP-SAT model proto.
absl::Span< const double > coefficients
::operations_research::sat::PartialVariableAssignment * mutable_solution_hint()
void AddHint(IntVar var, int64_t value)
Adds hinting to a variable.
Definition: cp_model.cc:1233
IntervalVar NewOptionalIntervalVar(const LinearExpr &start, const LinearExpr &size, const LinearExpr &end, BoolVar presence)
Creates an optional interval variable from 3 affine expressions and a Boolean variable.
Definition: cp_model.cc:710
LinearExpr StartExpr() const
Returns the start linear expression.
Definition: cp_model.cc:576
bool RefIsPositive(int ref)
LinearExpr SizeExpr() const
Returns the size linear expression.
Definition: cp_model.cc:583
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:86
IntVar * var
Definition: expr_array.cc:1874
Constraint AddLessOrEqual(const LinearExpr &left, const LinearExpr &right)
Adds left <= right.
Definition: cp_model.cc:820
::operations_research::sat::ReservoirConstraintProto * mutable_reservoir()
LinearExpr & operator-=(const LinearExpr &other)
Definition: cp_model.cc:263
std::string Name() const
Returns the name of the interval (or the empty string if not set).
Definition: cp_model.cc:604
std::string DebugString(const CpModelProto *proto=nullptr) const
Debug string.
Definition: cp_model.cc:279
Constraint AddLinearConstraint(const LinearExpr &expr, const Domain &domain)
Adds expr in domain.
Definition: cp_model.cc:850
Wrapper class around the cp_model proto.
Definition: cp_model.h:720
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
::operations_research::sat::IntegerVariableProto * mutable_variables(int index)
static DoubleLinearExpr WeightedSum(absl::Span< const IntVar > vars, absl::Span< const double > coeffs)
Constructs the scalar product of variables and coefficients.
Definition: cp_model.cc:346
Represents a Interval variable.
Definition: cp_model.h:446
const std::vector< int > & variables() const
Returns the vector of variable indices.
Definition: cp_model.h:404
int64_t value
Literal literal
Definition: optimization.cc:85
IntervalVar * interval
Definition: resource.cc:100
const Constraint * ct
void CopyFrom(const CpModelProto &model_proto)
Replaces the current model with the one from the given proto.
Definition: cp_model.cc:1266
Constraint AddMaxEquality(const LinearExpr &target, absl::Span< const IntVar > vars)
Adds target == max(vars).
Definition: cp_model.cc:1041