22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_format.h"
33 Demon* Solver::MakeConstraintInitialPropagateCallback(Constraint*
const ct) {
38 Demon* Solver::MakeDelayedConstraintInitialPropagateCallback(
39 Constraint*
const ct) {
45 class ActionDemon :
public Demon {
47 explicit ActionDemon(
const Solver::Action& action) : action_(action) {
48 CHECK(action !=
nullptr);
51 ~ActionDemon()
override {}
53 void Run(Solver*
const solver)
override { action_(solver); }
56 Solver::Action action_;
59 class ClosureDemon :
public Demon {
61 explicit ClosureDemon(
const Solver::Closure& closure) : closure_(closure) {
62 CHECK(closure !=
nullptr);
65 ~ClosureDemon()
override {}
67 void Run(Solver*
const solver)
override { closure_(); }
70 Solver::Closure closure_;
75 class TrueConstraint :
public Constraint {
77 explicit TrueConstraint(Solver*
const s) : Constraint(s) {}
78 ~TrueConstraint()
override {}
80 void Post()
override {}
81 void InitialPropagate()
override {}
82 std::string DebugString()
const override {
return "TrueConstraint()"; }
84 void Accept(ModelVisitor*
const visitor)
const override {
85 visitor->BeginVisitConstraint(ModelVisitor::kTrueConstraint,
this);
86 visitor->EndVisitConstraint(ModelVisitor::kTrueConstraint,
this);
88 IntVar* Var()
override {
return solver()->MakeIntConst(1); }
91 class FalseConstraint :
public Constraint {
93 explicit FalseConstraint(Solver*
const s) : Constraint(s) {}
94 FalseConstraint(Solver*
const s,
const std::string& explanation)
95 : Constraint(s), explanation_(explanation) {}
96 ~FalseConstraint()
override {}
98 void Post()
override {}
99 void InitialPropagate()
override { solver()->Fail(); }
100 std::string DebugString()
const override {
101 return absl::StrCat(
"FalseConstraint(", explanation_,
")");
104 void Accept(ModelVisitor*
const visitor)
const override {
105 visitor->BeginVisitConstraint(ModelVisitor::kFalseConstraint,
this);
106 visitor->EndVisitConstraint(ModelVisitor::kFalseConstraint,
this);
108 IntVar* Var()
override {
return solver()->MakeIntConst(0); }
111 const std::string explanation_;
120 class MapDomain :
public Constraint {
122 MapDomain(Solver*
const s, IntVar*
const var,
123 const std::vector<IntVar*>& actives)
124 : Constraint(s), var_(
var), actives_(actives) {
128 ~MapDomain()
override {}
130 void Post()
override {
133 var_->WhenDomain(vd);
137 std::unique_ptr<IntVarIterator> domain_it(
138 var_->MakeDomainIterator(
false));
139 for (
const int64 index : InitAndGetValues(domain_it.get())) {
140 if (
index >= 0 &&
index < actives_.size() && !actives_[
index]->Bound()) {
142 solver(),
this, &MapDomain::UpdateActive,
"UpdateActive",
index);
143 actives_[
index]->WhenDomain(d);
148 void InitialPropagate()
override {
149 for (
int i = 0; i < actives_.size(); ++i) {
151 if (!var_->Contains(i)) {
152 actives_[i]->SetValue(0);
153 }
else if (actives_[i]->Max() == 0LL) {
154 var_->RemoveValue(i);
156 if (actives_[i]->Min() == 1LL) {
166 IntVar*
const act = actives_[
index];
167 if (act->Max() == 0) {
168 var_->RemoveValue(
index);
169 }
else if (act->Min() == 1) {
170 var_->SetValue(
index);
175 const int64 oldmin = var_->OldMin();
176 const int64 oldmax = var_->OldMax();
177 const int64 vmin = var_->Min();
178 const int64 vmax = var_->Max();
179 const int64 size = actives_.size();
181 actives_[j]->SetValue(0);
184 if (j >= 0 && j < size) {
185 actives_[j]->SetValue(0);
190 actives_[j]->SetValue(
int64{0});
195 const int64 val = var_->Min();
196 if (val >= 0 && val < actives_.size()) {
197 actives_[val]->SetValue(1);
200 std::string DebugString()
const override {
201 return absl::StrFormat(
"MapDomain(%s, [%s])", var_->DebugString(),
205 void Accept(ModelVisitor*
const visitor)
const override {
206 visitor->BeginVisitConstraint(ModelVisitor::kMapDomain,
this);
207 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
209 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
211 visitor->EndVisitConstraint(ModelVisitor::kMapDomain,
this);
216 std::vector<IntVar*> actives_;
222 class LexicalLess :
public Constraint {
224 LexicalLess(Solver*
const s,
const std::vector<IntVar*>& left,
225 const std::vector<IntVar*>& right,
bool strict)
232 CHECK_EQ(left.size(), right.size());
235 ~LexicalLess()
override {}
237 void Post()
override {
238 const int position = JumpEqualVariables(0);
239 active_var_.SetValue(solver(), position);
240 if (position < left_.size()) {
241 demon_ = solver()->MakeConstraintInitialPropagateCallback(
this);
242 left_[position]->WhenRange(demon_);
243 right_[position]->WhenRange(demon_);
247 void InitialPropagate()
override {
248 const int position = JumpEqualVariables(active_var_.Value());
249 if (position >= left_.size()) {
255 if (position != active_var_.Value()) {
256 left_[position]->WhenRange(demon_);
257 right_[position]->WhenRange(demon_);
258 active_var_.SetValue(solver(), position);
260 const int next_non_equal = JumpEqualVariables(position + 1);
261 if ((strict_ && next_non_equal == left_.size()) ||
262 (next_non_equal < left_.size() &&
263 left_[next_non_equal]->Min() > right_[next_non_equal]->Max())) {
266 left_[position]->SetMax(right_[position]->Max() - 1);
267 right_[position]->SetMin(left_[position]->Min() + 1);
269 left_[position]->SetMax(right_[position]->Max());
270 right_[position]->SetMin(left_[position]->Min());
274 std::string DebugString()
const override {
275 return absl::StrFormat(
276 "%s([%s], [%s])", strict_ ?
"LexicalLess" :
"LexicalLessOrEqual",
280 void Accept(ModelVisitor*
const visitor)
const override {
281 visitor->BeginVisitConstraint(ModelVisitor::kLexLess,
this);
282 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kLeftArgument,
284 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kRightArgument,
286 visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, strict_);
287 visitor->EndVisitConstraint(ModelVisitor::kLexLess,
this);
291 int JumpEqualVariables(
int start_position)
const {
292 int position = start_position;
293 while (position < left_.size() && left_[position]->Bound() &&
294 right_[position]->Bound() &&
295 left_[position]->Min() == right_[position]->Min()) {
301 std::vector<IntVar*> left_;
302 std::vector<IntVar*> right_;
303 NumericalRev<int> active_var_;
310 class InversePermutationConstraint :
public Constraint {
312 InversePermutationConstraint(Solver*
const s,
313 const std::vector<IntVar*>& left,
314 const std::vector<IntVar*>& right)
318 left_hole_iterators_(left.size()),
319 left_domain_iterators_(left_.size()),
320 right_hole_iterators_(right_.size()),
321 right_domain_iterators_(right_.size()) {
322 CHECK_EQ(left_.size(), right_.size());
323 for (
int i = 0; i < left_.size(); ++i) {
324 left_hole_iterators_[i] = left_[i]->MakeHoleIterator(
true);
325 left_domain_iterators_[i] = left_[i]->MakeDomainIterator(
true);
326 right_hole_iterators_[i] = right_[i]->MakeHoleIterator(
true);
327 right_domain_iterators_[i] = right_[i]->MakeDomainIterator(
true);
331 ~InversePermutationConstraint()
override {}
333 void Post()
override {
334 for (
int i = 0; i < left_.size(); ++i) {
337 &InversePermutationConstraint::PropagateHolesOfLeftVarToRight,
338 "PropagateHolesOfLeftVarToRight", i);
339 left_[i]->WhenDomain(left_demon);
342 &InversePermutationConstraint::PropagateHolesOfRightVarToLeft,
343 "PropagateHolesOfRightVarToLeft", i);
344 right_[i]->WhenDomain(right_demon);
346 solver()->AddConstraint(
347 solver()->MakeAllDifferent(left_,
false));
348 solver()->AddConstraint(
349 solver()->MakeAllDifferent(right_,
false));
352 void InitialPropagate()
override {
353 const int size = left_.size();
354 for (
int i = 0; i < size; ++i) {
355 left_[i]->SetRange(0, size - 1);
356 right_[i]->SetRange(0, size - 1);
358 for (
int i = 0; i < size; ++i) {
359 PropagateDomain(i, left_[i], left_domain_iterators_[i], right_);
360 PropagateDomain(i, right_[i], right_domain_iterators_[i], left_);
364 void PropagateHolesOfLeftVarToRight(
int index) {
365 PropagateHoles(
index, left_[
index], left_hole_iterators_[
index], right_);
368 void PropagateHolesOfRightVarToLeft(
int index) {
369 PropagateHoles(
index, right_[
index], right_hole_iterators_[
index], left_);
372 std::string DebugString()
const override {
373 return absl::StrFormat(
"InversePermutationConstraint([%s], [%s])",
378 void Accept(ModelVisitor*
const visitor)
const override {
379 visitor->BeginVisitConstraint(ModelVisitor::kInversePermutation,
this);
380 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kLeftArgument,
382 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kRightArgument,
384 visitor->EndVisitConstraint(ModelVisitor::kInversePermutation,
this);
389 void PropagateHoles(
int index, IntVar*
const var, IntVarIterator*
const holes,
390 const std::vector<IntVar*>& inverse) {
399 for (
const int64 hole : InitAndGetValues(holes)) {
400 if (hole >= 0 && hole < left_.size()) {
401 inverse[hole]->RemoveValue(
index);
409 void PropagateDomain(
int index, IntVar*
const var,
410 IntVarIterator*
const domain,
411 const std::vector<IntVar*>& inverse) {
413 tmp_removed_values_.clear();
414 for (
const int64 value : InitAndGetValues(domain)) {
416 tmp_removed_values_.push_back(
value);
421 if (!tmp_removed_values_.empty()) {
422 var->RemoveValues(tmp_removed_values_);
426 std::vector<IntVar*> left_;
427 std::vector<IntVar*> right_;
428 std::vector<IntVarIterator*> left_hole_iterators_;
429 std::vector<IntVarIterator*> left_domain_iterators_;
430 std::vector<IntVarIterator*> right_hole_iterators_;
431 std::vector<IntVarIterator*> right_domain_iterators_;
434 std::vector<int64> tmp_removed_values_;
439 class IndexOfFirstMaxValue :
public Constraint {
441 IndexOfFirstMaxValue(Solver* solver, IntVar*
index,
442 const std::vector<IntVar*>& vars)
443 : Constraint(solver), index_(
index),
vars_(vars) {}
445 ~IndexOfFirstMaxValue()
override {}
447 void Post()
override {
449 solver()->MakeDelayedConstraintInitialPropagateCallback(
this);
450 index_->WhenRange(demon);
451 for (IntVar*
const var : vars_) {
452 var->WhenRange(demon);
456 void InitialPropagate()
override {
464 for (
int i = imin; i <= imax; ++i) {
465 max_max =
std::max(max_max, vars_[i]->Max());
466 max_min =
std::max(max_min, vars_[i]->Min());
471 for (
int i = 0; i < imin; ++i) {
472 vars_[i]->SetMax(max_max - 1);
474 for (
int i = imax + 1; i < vsize; ++i) {
475 vars_[i]->SetMax(max_max);
479 int64 min_index = imin;
480 while (vars_[min_index]->Max() < max_min) {
483 int64 max_index = imax;
484 while (vars_[max_index]->Max() < max_min) {
487 index_->SetRange(min_index, max_index);
490 std::string DebugString()
const override {
491 return absl::StrFormat(
"IndexMax(%s, [%s])", index_->DebugString(),
495 void Accept(ModelVisitor*
const visitor)
const override {
500 IntVar*
const index_;
501 const std::vector<IntVar*>
vars_;
507 Demon* Solver::MakeActionDemon(Solver::Action action) {
508 return RevAlloc(
new ActionDemon(action));
511 Demon* Solver::MakeClosureDemon(Solver::Closure closure) {
512 return RevAlloc(
new ClosureDemon(closure));
515 Constraint* Solver::MakeTrueConstraint() {
516 DCHECK(true_constraint_ !=
nullptr);
517 return true_constraint_;
520 Constraint* Solver::MakeFalseConstraint() {
521 DCHECK(false_constraint_ !=
nullptr);
522 return false_constraint_;
524 Constraint* Solver::MakeFalseConstraint(
const std::string& explanation) {
525 return RevAlloc(
new FalseConstraint(
this, explanation));
528 void Solver::InitCachedConstraint() {
529 DCHECK(true_constraint_ ==
nullptr);
530 true_constraint_ = RevAlloc(
new TrueConstraint(
this));
531 DCHECK(false_constraint_ ==
nullptr);
532 false_constraint_ = RevAlloc(
new FalseConstraint(
this));
535 Constraint* Solver::MakeMapDomain(IntVar*
const var,
536 const std::vector<IntVar*>& actives) {
537 return RevAlloc(
new MapDomain(
this,
var, actives));
540 Constraint* Solver::MakeLexicalLess(
const std::vector<IntVar*>& left,
541 const std::vector<IntVar*>& right) {
542 return RevAlloc(
new LexicalLess(
this, left, right,
true));
545 Constraint* Solver::MakeLexicalLessOrEqual(
const std::vector<IntVar*>& left,
546 const std::vector<IntVar*>& right) {
547 return RevAlloc(
new LexicalLess(
this, left, right,
false));
550 Constraint* Solver::MakeInversePermutationConstraint(
551 const std::vector<IntVar*>& left,
const std::vector<IntVar*>& right) {
552 return RevAlloc(
new InversePermutationConstraint(
this, left, right));
555 Constraint* Solver::MakeIndexOfFirstMaxValueConstraint(
556 IntVar*
index,
const std::vector<IntVar*>& vars) {
557 return RevAlloc(
new IndexOfFirstMaxValue(
this,
index, vars));
560 Constraint* Solver::MakeIndexOfFirstMinValueConstraint(
561 IntVar*
index,
const std::vector<IntVar*>& vars) {
562 std::vector<IntVar*> opp_vars(vars.size());
563 for (
int i = 0; i < vars.size(); ++i) {
564 opp_vars[i] = MakeOpposite(vars[i])->Var();
566 return RevAlloc(
new IndexOfFirstMaxValue(
this,
index, opp_vars));