22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_format.h"
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); }
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_(); }
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 {
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 {
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 {
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 {
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 {
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_;
508 return RevAlloc(
new ActionDemon(action));
512 return RevAlloc(
new ClosureDemon(closure));
516 DCHECK(true_constraint_ !=
nullptr);
517 return true_constraint_;
521 DCHECK(false_constraint_ !=
nullptr);
522 return false_constraint_;
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));
536 const std::vector<IntVar*>& actives) {
537 return RevAlloc(
new MapDomain(
this,
var, actives));
541 const std::vector<IntVar*>& right) {
542 return RevAlloc(
new LexicalLess(
this, left, right,
true));
546 const std::vector<IntVar*>& right) {
547 return RevAlloc(
new LexicalLess(
this, left, right,
false));
551 const std::vector<IntVar*>& left,
const std::vector<IntVar*>& right) {
552 return RevAlloc(
new InversePermutationConstraint(
this, left, right));
557 return RevAlloc(
new IndexOfFirstMaxValue(
this,
index, vars));
562 std::vector<IntVar*> opp_vars(vars.size());
563 for (
int i = 0; i < vars.size(); ++i) {
566 return RevAlloc(
new IndexOfFirstMaxValue(
this,
index, opp_vars));