OR-Tools  8.0
constraint_solver.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //
15 // This file implements the core objects of the constraint solver:
16 // Solver, Search, Queue, ... along with the main resolution loop.
17 
19 
20 #include <csetjmp>
21 #include <deque>
22 #include <iosfwd>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 
27 #include "absl/memory/memory.h"
28 #include "absl/time/clock.h"
29 #include "absl/time/time.h"
31 #include "ortools/base/file.h"
33 #include "ortools/base/logging.h"
34 #include "ortools/base/macros.h"
35 #include "ortools/base/map_util.h"
36 #include "ortools/base/recordio.h"
37 #include "ortools/base/stl_util.h"
39 #include "ortools/util/tuple_set.h"
40 #include "zlib.h"
41 
42 // These flags are used to set the fields in the DefaultSolverParameters proto.
43 DEFINE_bool(cp_trace_propagation, false,
44  "Trace propagation events (constraint and demon executions,"
45  " variable modifications).");
46 DEFINE_bool(cp_trace_search, false, "Trace search events");
47 DEFINE_bool(cp_print_added_constraints, false,
48  "show all constraints added to the solver.");
49 DEFINE_bool(cp_print_model, false,
50  "use PrintModelVisitor on model before solving.");
51 DEFINE_bool(cp_model_stats, false,
52  "use StatisticsModelVisitor on model before solving.");
53 DEFINE_bool(cp_disable_solve, false,
54  "Force failure at the beginning of a search.");
55 DEFINE_string(cp_profile_file, "", "Export profiling overview to file.");
56 DEFINE_bool(cp_print_local_search_profile, false,
57  "Print local search profiling data after solving.");
58 DEFINE_bool(cp_name_variables, false, "Force all variables to have names.");
59 DEFINE_bool(cp_name_cast_variables, false,
60  "Name variables casted from expressions");
61 DEFINE_bool(cp_use_small_table, true,
62  "Use small compact table constraint when possible.");
63 DEFINE_bool(cp_use_cumulative_edge_finder, true,
64  "Use the O(n log n) cumulative edge finding algorithm described "
65  "in 'Edge Finding Filtering Algorithm for Discrete Cumulative "
66  "Resources in O(kn log n)' by Petr Vilim, CP 2009.");
67 DEFINE_bool(cp_use_cumulative_time_table, true,
68  "Use a O(n^2) cumulative time table propagation algorithm.");
69 DEFINE_bool(cp_use_cumulative_time_table_sync, false,
70  "Use a synchronized O(n^2 log n) cumulative time table propagation "
71  "algorithm.");
72 DEFINE_bool(cp_use_sequence_high_demand_tasks, true,
73  "Use a sequence constraints for cumulative tasks that have a "
74  "demand greater than half of the capacity of the resource.");
75 DEFINE_bool(cp_use_all_possible_disjunctions, true,
76  "Post temporal disjunctions for all pairs of tasks sharing a "
77  "cumulative resource and that cannot overlap because the sum of "
78  "their demand exceeds the capacity.");
79 DEFINE_int32(cp_max_edge_finder_size, 50,
80  "Do not post the edge finder in the cumulative constraints if "
81  "it contains more than this number of tasks");
82 DEFINE_bool(cp_diffn_use_cumulative, true,
83  "Diffn constraint adds redundant cumulative constraint");
84 DEFINE_bool(cp_use_element_rmq, true,
85  "If true, rmq's will be used in element expressions.");
86 DEFINE_int32(cp_check_solution_period, 1,
87  "Number of solutions explored between two solution checks during "
88  "local search.");
89 DEFINE_int64(cp_random_seed, 12345,
90  "Random seed used in several (but not all) random number "
91  "generators used by the CP solver. Use -1 to auto-generate an"
92  "undeterministic random seed.");
93 
94 void ConstraintSolverFailsHere() { VLOG(3) << "Fail"; }
95 
96 #if defined(_MSC_VER) // WINDOWS
97 #pragma warning(disable : 4351 4355)
98 #endif
99 
100 namespace operations_research {
101 
102 namespace {
103 // Calls the given method with the provided arguments on all objects in the
104 // collection.
105 template <typename T, typename MethodPointer, typename... Args>
106 void ForAll(const std::vector<T*>& objects, MethodPointer method,
107  const Args&... args) {
108  for (T* const object : objects) {
109  DCHECK(object != nullptr);
110  (object->*method)(args...);
111  }
112 }
113 } // namespace
114 
115 // ----- ConstraintSolverParameters -----
116 
117 ConstraintSolverParameters Solver::DefaultSolverParameters() {
118  ConstraintSolverParameters params;
119  params.set_compress_trail(ConstraintSolverParameters::NO_COMPRESSION);
120  params.set_trail_block_size(8000);
121  params.set_array_split_size(16);
122  params.set_store_names(true);
123  params.set_profile_propagation(!FLAGS_cp_profile_file.empty());
124  params.set_trace_propagation(FLAGS_cp_trace_propagation);
125  params.set_trace_search(FLAGS_cp_trace_search);
126  params.set_name_all_variables(FLAGS_cp_name_variables);
127  params.set_profile_file(FLAGS_cp_profile_file);
128  params.set_profile_local_search(FLAGS_cp_print_local_search_profile);
129  params.set_print_local_search_profile(FLAGS_cp_print_local_search_profile);
130  params.set_print_model(FLAGS_cp_print_model);
131  params.set_print_model_stats(FLAGS_cp_model_stats);
132  params.set_disable_solve(FLAGS_cp_disable_solve);
133  params.set_name_cast_variables(FLAGS_cp_name_cast_variables);
134  params.set_print_added_constraints(FLAGS_cp_print_added_constraints);
135  params.set_use_small_table(FLAGS_cp_use_small_table);
136  params.set_use_cumulative_edge_finder(FLAGS_cp_use_cumulative_edge_finder);
137  params.set_use_cumulative_time_table(FLAGS_cp_use_cumulative_time_table);
138  params.set_use_cumulative_time_table_sync(
139  FLAGS_cp_use_cumulative_time_table_sync);
140  params.set_use_sequence_high_demand_tasks(
141  FLAGS_cp_use_sequence_high_demand_tasks);
142  params.set_use_all_possible_disjunctions(
143  FLAGS_cp_use_all_possible_disjunctions);
144  params.set_max_edge_finder_size(FLAGS_cp_max_edge_finder_size);
145  params.set_diffn_use_cumulative(FLAGS_cp_diffn_use_cumulative);
146  params.set_use_element_rmq(FLAGS_cp_use_element_rmq);
147  params.set_check_solution_period(FLAGS_cp_check_solution_period);
148  return params;
149 }
150 
151 // ----- Forward Declarations and Profiling Support -----
152 extern DemonProfiler* BuildDemonProfiler(Solver* const solver);
153 extern void DeleteDemonProfiler(DemonProfiler* const monitor);
154 extern void InstallDemonProfiler(DemonProfiler* const monitor);
155 extern LocalSearchProfiler* BuildLocalSearchProfiler(Solver* solver);
156 extern void DeleteLocalSearchProfiler(LocalSearchProfiler* monitor);
157 extern void InstallLocalSearchProfiler(LocalSearchProfiler* monitor);
158 
159 // TODO(user): remove this complex logic.
160 // We need the double test because parameters are set too late when using
161 // python in the open source. This is the cheapest work-around.
162 bool Solver::InstrumentsDemons() const {
163  return IsProfilingEnabled() || InstrumentsVariables();
164 }
165 
166 bool Solver::IsProfilingEnabled() const {
167  return parameters_.profile_propagation() ||
168  !parameters_.profile_file().empty();
169 }
170 
171 bool Solver::IsLocalSearchProfilingEnabled() const {
172  return parameters_.profile_local_search() ||
173  parameters_.print_local_search_profile();
174 }
175 
176 bool Solver::InstrumentsVariables() const {
177  return parameters_.trace_propagation();
178 }
179 
180 bool Solver::NameAllVariables() const {
181  return parameters_.name_all_variables();
182 }
183 
184 // ------------------ Demon class ----------------
185 
186 Solver::DemonPriority Demon::priority() const {
187  return Solver::NORMAL_PRIORITY;
188 }
189 
190 std::string Demon::DebugString() const { return "Demon"; }
191 
192 void Demon::inhibit(Solver* const s) {
193  if (stamp_ < kuint64max) {
194  s->SaveAndSetValue(&stamp_, kuint64max);
195  }
196 }
197 
198 void Demon::desinhibit(Solver* const s) {
199  if (stamp_ == kuint64max) {
200  s->SaveAndSetValue(&stamp_, s->stamp() - 1);
201  }
202 }
203 
204 // ------------------ Queue class ------------------
205 
206 extern void CleanVariableOnFail(IntVar* const var);
207 
208 class Queue {
209  public:
210  static constexpr int64 kTestPeriod = 10000;
211 
212  explicit Queue(Solver* const s)
213  : solver_(s),
214  stamp_(1),
215  freeze_level_(0),
216  in_process_(false),
217  clean_action_(nullptr),
218  clean_variable_(nullptr),
219  in_add_(false),
220  instruments_demons_(s->InstrumentsDemons()) {}
221 
222  ~Queue() {}
223 
224  void Freeze() {
225  freeze_level_++;
226  stamp_++;
227  }
228 
229  void Unfreeze() {
230  if (--freeze_level_ == 0) {
231  Process();
232  }
233  }
234 
235  void ProcessOneDemon(Demon* const demon) {
236  demon->set_stamp(stamp_ - 1);
237  if (!instruments_demons_) {
238  if (++solver_->demon_runs_[demon->priority()] % kTestPeriod == 0) {
239  solver_->TopPeriodicCheck();
240  }
241  demon->Run(solver_);
242  solver_->CheckFail();
243  } else {
244  solver_->GetPropagationMonitor()->BeginDemonRun(demon);
245  if (++solver_->demon_runs_[demon->priority()] % kTestPeriod == 0) {
246  solver_->TopPeriodicCheck();
247  }
248  demon->Run(solver_);
249  solver_->CheckFail();
250  solver_->GetPropagationMonitor()->EndDemonRun(demon);
251  }
252  }
253 
254  void Process() {
255  if (!in_process_) {
256  in_process_ = true;
257  while (!var_queue_.empty() || !delayed_queue_.empty()) {
258  if (!var_queue_.empty()) {
259  Demon* const demon = var_queue_.front();
260  var_queue_.pop_front();
261  ProcessOneDemon(demon);
262  } else {
263  DCHECK(!delayed_queue_.empty());
264  Demon* const demon = delayed_queue_.front();
265  delayed_queue_.pop_front();
266  ProcessOneDemon(demon);
267  }
268  }
269  in_process_ = false;
270  }
271  }
272 
273  void ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
274  if (!instruments_demons_) {
275  for (SimpleRevFIFO<Demon*>::Iterator it(&demons); it.ok(); ++it) {
276  Demon* const demon = *it;
277  if (demon->stamp() < stamp_) {
278  DCHECK_EQ(demon->priority(), Solver::NORMAL_PRIORITY);
279  if (++solver_->demon_runs_[Solver::NORMAL_PRIORITY] % kTestPeriod ==
280  0) {
281  solver_->TopPeriodicCheck();
282  }
283  demon->Run(solver_);
284  solver_->CheckFail();
285  }
286  }
287  } else {
288  for (SimpleRevFIFO<Demon*>::Iterator it(&demons); it.ok(); ++it) {
289  Demon* const demon = *it;
290  if (demon->stamp() < stamp_) {
291  DCHECK_EQ(demon->priority(), Solver::NORMAL_PRIORITY);
292  solver_->GetPropagationMonitor()->BeginDemonRun(demon);
293  if (++solver_->demon_runs_[Solver::NORMAL_PRIORITY] % kTestPeriod ==
294  0) {
295  solver_->TopPeriodicCheck();
296  }
297  demon->Run(solver_);
298  solver_->CheckFail();
299  solver_->GetPropagationMonitor()->EndDemonRun(demon);
300  }
301  }
302  }
303  }
304 
305  void EnqueueAll(const SimpleRevFIFO<Demon*>& demons) {
306  for (SimpleRevFIFO<Demon*>::Iterator it(&demons); it.ok(); ++it) {
307  EnqueueDelayedDemon(*it);
308  }
309  }
310 
311  void EnqueueVar(Demon* const demon) {
312  DCHECK(demon->priority() == Solver::VAR_PRIORITY);
313  if (demon->stamp() < stamp_) {
314  demon->set_stamp(stamp_);
315  var_queue_.push_back(demon);
316  if (freeze_level_ == 0) {
317  Process();
318  }
319  }
320  }
321 
322  void EnqueueDelayedDemon(Demon* const demon) {
323  DCHECK(demon->priority() == Solver::DELAYED_PRIORITY);
324  if (demon->stamp() < stamp_) {
325  demon->set_stamp(stamp_);
326  delayed_queue_.push_back(demon);
327  }
328  }
329 
330  void AfterFailure() {
331  // Clean queue.
332  var_queue_.clear();
333  delayed_queue_.clear();
334 
335  // Call cleaning actions on variables.
336  if (clean_action_ != nullptr) {
337  clean_action_(solver_);
338  clean_action_ = nullptr;
339  } else if (clean_variable_ != nullptr) {
340  CleanVariableOnFail(clean_variable_);
341  clean_variable_ = nullptr;
342  }
343 
344  freeze_level_ = 0;
345  in_process_ = false;
346  in_add_ = false;
347  to_add_.clear();
348  }
349 
350  void increase_stamp() { stamp_++; }
351 
352  uint64 stamp() const { return stamp_; }
353 
354  void set_action_on_fail(Solver::Action a) {
355  DCHECK(clean_variable_ == nullptr);
356  clean_action_ = std::move(a);
357  }
358 
360  DCHECK(clean_action_ == nullptr);
361  clean_variable_ = var;
362  }
363 
365  DCHECK(clean_variable_ == nullptr);
366  clean_action_ = nullptr;
367  }
368 
369  void AddConstraint(Constraint* const c) {
370  to_add_.push_back(c);
372  }
373 
375  if (!in_add_) {
376  in_add_ = true;
377  // We cannot store to_add_.size() as constraints can add other
378  // constraints. For the same reason a range-based for loop cannot be used.
379  // TODO(user): Make to_add_ a queue to make the behavior more obvious.
380  for (int counter = 0; counter < to_add_.size(); ++counter) {
381  Constraint* const constraint = to_add_[counter];
382  // TODO(user): Add profiling to initial propagation
383  constraint->PostAndPropagate();
384  }
385  in_add_ = false;
386  to_add_.clear();
387  }
388  }
389 
390  private:
391  Solver* const solver_;
392  std::deque<Demon*> var_queue_;
393  std::deque<Demon*> delayed_queue_;
394  uint64 stamp_;
395  // The number of nested freeze levels. The queue is frozen if and only if
396  // freeze_level_ > 0.
397  uint32 freeze_level_;
398  bool in_process_;
399  Solver::Action clean_action_;
400  IntVar* clean_variable_;
401  std::vector<Constraint*> to_add_;
402  bool in_add_;
403  const bool instruments_demons_;
404 };
405 
406 // ------------------ StateMarker / StateInfo struct -----------
407 
408 struct StateInfo { // This is an internal structure to store
409  // additional information on the choice point.
410  public:
412  : ptr_info(nullptr),
413  int_info(0),
414  depth(0),
415  left_depth(0),
416  reversible_action(nullptr) {}
417  StateInfo(void* pinfo, int iinfo)
418  : ptr_info(pinfo),
419  int_info(iinfo),
420  depth(0),
421  left_depth(0),
422  reversible_action(nullptr) {}
423  StateInfo(void* pinfo, int iinfo, int d, int ld)
424  : ptr_info(pinfo),
425  int_info(iinfo),
426  depth(d),
427  left_depth(ld),
428  reversible_action(nullptr) {}
429  StateInfo(Solver::Action a, bool fast)
430  : ptr_info(nullptr),
431  int_info(static_cast<int>(fast)),
432  depth(0),
433  left_depth(0),
434  reversible_action(std::move(a)) {}
435 
436  void* ptr_info;
437  int int_info;
438  int depth;
440  Solver::Action reversible_action;
441 };
442 
443 struct StateMarker {
444  public:
445  StateMarker(Solver::MarkerType t, const StateInfo& info);
446  friend class Solver;
447  friend struct Trail;
448 
449  private:
450  Solver::MarkerType type_;
451  int rev_int_index_;
452  int rev_int64_index_;
453  int rev_uint64_index_;
454  int rev_double_index_;
455  int rev_ptr_index_;
456  int rev_boolvar_list_index_;
457  int rev_bools_index_;
458  int rev_int_memory_index_;
459  int rev_int64_memory_index_;
460  int rev_double_memory_index_;
461  int rev_object_memory_index_;
462  int rev_object_array_memory_index_;
463  int rev_memory_index_;
464  int rev_memory_array_index_;
465  StateInfo info_;
466 };
467 
468 StateMarker::StateMarker(Solver::MarkerType t, const StateInfo& info)
469  : type_(t),
470  rev_int_index_(0),
471  rev_int64_index_(0),
472  rev_uint64_index_(0),
473  rev_double_index_(0),
474  rev_ptr_index_(0),
475  rev_boolvar_list_index_(0),
476  rev_bools_index_(0),
477  rev_int_memory_index_(0),
478  rev_int64_memory_index_(0),
479  rev_double_memory_index_(0),
480  rev_object_memory_index_(0),
481  rev_object_array_memory_index_(0),
482  info_(info) {}
483 
484 // ---------- Trail and Reversibility ----------
485 
486 namespace {
487 // ----- addrval struct -----
488 
489 // This template class is used internally to implement reversibility.
490 // It stores an address and the value that was at the address.
491 template <class T>
492 struct addrval {
493  public:
494  addrval() : address_(nullptr) {}
495  explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
496  void restore() const { (*address_) = old_value_; }
497 
498  private:
499  T* address_;
500  T old_value_;
501 };
502 
503 // ----- Compressed trail -----
504 
505 // ---------- Trail Packer ---------
506 // Abstract class to pack trail blocks.
507 
508 template <class T>
509 class TrailPacker {
510  public:
511  explicit TrailPacker(int block_size) : block_size_(block_size) {}
512  virtual ~TrailPacker() {}
513  int input_size() const { return block_size_ * sizeof(addrval<T>); }
514  virtual void Pack(const addrval<T>* block, std::string* packed_block) = 0;
515  virtual void Unpack(const std::string& packed_block, addrval<T>* block) = 0;
516 
517  private:
518  const int block_size_;
519  DISALLOW_COPY_AND_ASSIGN(TrailPacker);
520 };
521 
522 template <class T>
523 class NoCompressionTrailPacker : public TrailPacker<T> {
524  public:
525  explicit NoCompressionTrailPacker(int block_size)
526  : TrailPacker<T>(block_size) {}
527  ~NoCompressionTrailPacker() override {}
528  void Pack(const addrval<T>* block, std::string* packed_block) override {
529  DCHECK(block != nullptr);
530  DCHECK(packed_block != nullptr);
531  absl::string_view block_str(reinterpret_cast<const char*>(block),
532  this->input_size());
533  packed_block->assign(block_str.data(), block_str.size());
534  }
535  void Unpack(const std::string& packed_block, addrval<T>* block) override {
536  DCHECK(block != nullptr);
537  memcpy(block, packed_block.c_str(), packed_block.size());
538  }
539 
540  private:
541  DISALLOW_COPY_AND_ASSIGN(NoCompressionTrailPacker<T>);
542 };
543 
544 template <class T>
545 class ZlibTrailPacker : public TrailPacker<T> {
546  public:
547  explicit ZlibTrailPacker(int block_size)
548  : TrailPacker<T>(block_size),
549  tmp_size_(compressBound(this->input_size())),
550  tmp_block_(new char[tmp_size_]) {}
551 
552  ~ZlibTrailPacker() override {}
553 
554  void Pack(const addrval<T>* block, std::string* packed_block) override {
555  DCHECK(block != nullptr);
556  DCHECK(packed_block != nullptr);
557  uLongf size = tmp_size_;
558  const int result =
559  compress(reinterpret_cast<Bytef*>(tmp_block_.get()), &size,
560  reinterpret_cast<const Bytef*>(block), this->input_size());
561  CHECK_EQ(Z_OK, result);
562  absl::string_view block_str;
563  block_str = absl::string_view(tmp_block_.get(), size);
564  packed_block->assign(block_str.data(), block_str.size());
565  }
566 
567  void Unpack(const std::string& packed_block, addrval<T>* block) override {
568  DCHECK(block != nullptr);
569  uLongf size = this->input_size();
570  const int result =
571  uncompress(reinterpret_cast<Bytef*>(block), &size,
572  reinterpret_cast<const Bytef*>(packed_block.c_str()),
573  packed_block.size());
574  CHECK_EQ(Z_OK, result);
575  }
576 
577  private:
578  const uint64 tmp_size_;
579  std::unique_ptr<char[]> tmp_block_;
580  DISALLOW_COPY_AND_ASSIGN(ZlibTrailPacker<T>);
581 };
582 
583 template <class T>
584 class CompressedTrail {
585  public:
586  CompressedTrail(
587  int block_size,
588  ConstraintSolverParameters::TrailCompression compression_level)
589  : block_size_(block_size),
590  blocks_(nullptr),
591  free_blocks_(nullptr),
592  data_(new addrval<T>[block_size]),
593  buffer_(new addrval<T>[block_size]),
594  buffer_used_(false),
595  current_(0),
596  size_(0) {
597  switch (compression_level) {
598  case ConstraintSolverParameters::NO_COMPRESSION: {
599  packer_.reset(new NoCompressionTrailPacker<T>(block_size));
600  break;
601  }
602  case ConstraintSolverParameters::COMPRESS_WITH_ZLIB: {
603  packer_.reset(new ZlibTrailPacker<T>(block_size));
604  break;
605  }
606  default: {
607  LOG(ERROR) << "Should not be here";
608  }
609  }
610 
611  // We zero all memory used by addrval arrays.
612  // Because of padding, all bytes may not be initialized, while compression
613  // will read them all, even if the uninitialized bytes are never used.
614  // This makes valgrind happy.
615 
616  memset(data_.get(), 0, sizeof(*data_.get()) * block_size);
617  memset(buffer_.get(), 0, sizeof(*buffer_.get()) * block_size);
618  }
619  ~CompressedTrail() {
620  FreeBlocks(blocks_);
621  FreeBlocks(free_blocks_);
622  }
623  const addrval<T>& Back() const {
624  // Back of empty trail.
625  DCHECK_GT(current_, 0);
626  return data_[current_ - 1];
627  }
628  void PopBack() {
629  if (size_ > 0) {
630  --current_;
631  if (current_ <= 0) {
632  if (buffer_used_) {
633  data_.swap(buffer_);
634  current_ = block_size_;
635  buffer_used_ = false;
636  } else if (blocks_ != nullptr) {
637  packer_->Unpack(blocks_->compressed, data_.get());
638  FreeTopBlock();
639  current_ = block_size_;
640  }
641  }
642  --size_;
643  }
644  }
645  void PushBack(const addrval<T>& addr_val) {
646  if (current_ >= block_size_) {
647  if (buffer_used_) { // Buffer is used.
648  NewTopBlock();
649  packer_->Pack(buffer_.get(), &blocks_->compressed);
650  // O(1) operation.
651  data_.swap(buffer_);
652  } else {
653  data_.swap(buffer_);
654  buffer_used_ = true;
655  }
656  current_ = 0;
657  }
658  data_[current_] = addr_val;
659  ++current_;
660  ++size_;
661  }
662  int64 size() const { return size_; }
663 
664  private:
665  struct Block {
666  std::string compressed;
667  Block* next;
668  };
669 
670  void FreeTopBlock() {
671  Block* block = blocks_;
672  blocks_ = block->next;
673  block->compressed.clear();
674  block->next = free_blocks_;
675  free_blocks_ = block;
676  }
677  void NewTopBlock() {
678  Block* block = nullptr;
679  if (free_blocks_ != nullptr) {
680  block = free_blocks_;
681  free_blocks_ = block->next;
682  } else {
683  block = new Block;
684  }
685  block->next = blocks_;
686  blocks_ = block;
687  }
688  void FreeBlocks(Block* blocks) {
689  while (nullptr != blocks) {
690  Block* next = blocks->next;
691  delete blocks;
692  blocks = next;
693  }
694  }
695 
696  std::unique_ptr<TrailPacker<T> > packer_;
697  const int block_size_;
698  Block* blocks_;
699  Block* free_blocks_;
700  std::unique_ptr<addrval<T>[]> data_;
701  std::unique_ptr<addrval<T>[]> buffer_;
702  bool buffer_used_;
703  int current_;
704  int size_;
705 };
706 } // namespace
707 
708 // ----- Trail -----
709 
710 // Object are explicitly copied using the copy ctor instead of
711 // passing and storing a pointer. As objects are small, copying is
712 // much faster than allocating (around 35% on a complete solve).
713 
714 extern void RestoreBoolValue(IntVar* const var);
715 
716 struct Trail {
717  CompressedTrail<int> rev_ints_;
718  CompressedTrail<int64> rev_int64s_;
719  CompressedTrail<uint64> rev_uint64s_;
720  CompressedTrail<double> rev_doubles_;
721  CompressedTrail<void*> rev_ptrs_;
722  std::vector<IntVar*> rev_boolvar_list_;
723  std::vector<bool*> rev_bools_;
724  std::vector<bool> rev_bool_value_;
725  std::vector<int*> rev_int_memory_;
726  std::vector<int64*> rev_int64_memory_;
727  std::vector<double*> rev_double_memory_;
728  std::vector<BaseObject*> rev_object_memory_;
729  std::vector<BaseObject**> rev_object_array_memory_;
730  std::vector<void*> rev_memory_;
731  std::vector<void**> rev_memory_array_;
732 
733  Trail(int block_size,
734  ConstraintSolverParameters::TrailCompression compression_level)
735  : rev_ints_(block_size, compression_level),
736  rev_int64s_(block_size, compression_level),
737  rev_uint64s_(block_size, compression_level),
738  rev_doubles_(block_size, compression_level),
739  rev_ptrs_(block_size, compression_level) {}
740 
742  int target = m->rev_int_index_;
743  for (int curr = rev_ints_.size(); curr > target; --curr) {
744  const addrval<int>& cell = rev_ints_.Back();
745  cell.restore();
746  rev_ints_.PopBack();
747  }
748  DCHECK_EQ(rev_ints_.size(), target);
749  // Incorrect trail size after backtrack.
750  target = m->rev_int64_index_;
751  for (int curr = rev_int64s_.size(); curr > target; --curr) {
752  const addrval<int64>& cell = rev_int64s_.Back();
753  cell.restore();
754  rev_int64s_.PopBack();
755  }
756  DCHECK_EQ(rev_int64s_.size(), target);
757  // Incorrect trail size after backtrack.
758  target = m->rev_uint64_index_;
759  for (int curr = rev_uint64s_.size(); curr > target; --curr) {
760  const addrval<uint64>& cell = rev_uint64s_.Back();
761  cell.restore();
762  rev_uint64s_.PopBack();
763  }
764  DCHECK_EQ(rev_uint64s_.size(), target);
765  // Incorrect trail size after backtrack.
766  target = m->rev_double_index_;
767  for (int curr = rev_doubles_.size(); curr > target; --curr) {
768  const addrval<double>& cell = rev_doubles_.Back();
769  cell.restore();
770  rev_doubles_.PopBack();
771  }
772  DCHECK_EQ(rev_doubles_.size(), target);
773  // Incorrect trail size after backtrack.
774  target = m->rev_ptr_index_;
775  for (int curr = rev_ptrs_.size(); curr > target; --curr) {
776  const addrval<void*>& cell = rev_ptrs_.Back();
777  cell.restore();
778  rev_ptrs_.PopBack();
779  }
780  DCHECK_EQ(rev_ptrs_.size(), target);
781  // Incorrect trail size after backtrack.
782  target = m->rev_boolvar_list_index_;
783  for (int curr = rev_boolvar_list_.size() - 1; curr >= target; --curr) {
784  IntVar* const var = rev_boolvar_list_[curr];
786  }
787  rev_boolvar_list_.resize(target);
788 
789  DCHECK_EQ(rev_bools_.size(), rev_bool_value_.size());
790  target = m->rev_bools_index_;
791  for (int curr = rev_bools_.size() - 1; curr >= target; --curr) {
792  *(rev_bools_[curr]) = rev_bool_value_[curr];
793  }
794  rev_bools_.resize(target);
795  rev_bool_value_.resize(target);
796 
797  target = m->rev_int_memory_index_;
798  for (int curr = rev_int_memory_.size() - 1; curr >= target; --curr) {
799  delete[] rev_int_memory_[curr];
800  }
801  rev_int_memory_.resize(target);
802 
803  target = m->rev_int64_memory_index_;
804  for (int curr = rev_int64_memory_.size() - 1; curr >= target; --curr) {
805  delete[] rev_int64_memory_[curr];
806  }
807  rev_int64_memory_.resize(target);
808 
809  target = m->rev_double_memory_index_;
810  for (int curr = rev_double_memory_.size() - 1; curr >= target; --curr) {
811  delete[] rev_double_memory_[curr];
812  }
813  rev_double_memory_.resize(target);
814 
815  target = m->rev_object_memory_index_;
816  for (int curr = rev_object_memory_.size() - 1; curr >= target; --curr) {
817  delete rev_object_memory_[curr];
818  }
819  rev_object_memory_.resize(target);
820 
821  target = m->rev_object_array_memory_index_;
822  for (int curr = rev_object_array_memory_.size() - 1; curr >= target;
823  --curr) {
824  delete[] rev_object_array_memory_[curr];
825  }
826  rev_object_array_memory_.resize(target);
827 
828  target = m->rev_memory_index_;
829  for (int curr = rev_memory_.size() - 1; curr >= target; --curr) {
830  // Explicitly call unsized delete
831  ::operator delete(reinterpret_cast<char*>(rev_memory_[curr]));
832  // The previous cast is necessary to deallocate generic memory
833  // described by a void* when passed to the RevAlloc procedure
834  // We cannot do a delete[] there
835  // This is useful for cells of RevFIFO and should not be used outside
836  // of the product
837  }
838  rev_memory_.resize(target);
839 
840  target = m->rev_memory_array_index_;
841  for (int curr = rev_memory_array_.size() - 1; curr >= target; --curr) {
842  delete[] rev_memory_array_[curr];
843  // delete [] version of the previous unsafe case.
844  }
845  rev_memory_array_.resize(target);
846  }
847 };
848 
849 void Solver::InternalSaveValue(int* valptr) {
850  trail_->rev_ints_.PushBack(addrval<int>(valptr));
851 }
852 
853 void Solver::InternalSaveValue(int64* valptr) {
854  trail_->rev_int64s_.PushBack(addrval<int64>(valptr));
855 }
856 
857 void Solver::InternalSaveValue(uint64* valptr) {
858  trail_->rev_uint64s_.PushBack(addrval<uint64>(valptr));
859 }
860 
861 void Solver::InternalSaveValue(double* valptr) {
862  trail_->rev_doubles_.PushBack(addrval<double>(valptr));
863 }
864 
865 void Solver::InternalSaveValue(void** valptr) {
866  trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
867 }
868 
869 // TODO(user) : this code is unsafe if you save the same alternating
870 // bool multiple times.
871 // The correct code should use a bitset and a single list.
872 void Solver::InternalSaveValue(bool* valptr) {
873  trail_->rev_bools_.push_back(valptr);
874  trail_->rev_bool_value_.push_back(*valptr);
875 }
876 
877 BaseObject* Solver::SafeRevAlloc(BaseObject* ptr) {
878  check_alloc_state();
879  trail_->rev_object_memory_.push_back(ptr);
880  return ptr;
881 }
882 
883 int* Solver::SafeRevAllocArray(int* ptr) {
884  check_alloc_state();
885  trail_->rev_int_memory_.push_back(ptr);
886  return ptr;
887 }
888 
889 int64* Solver::SafeRevAllocArray(int64* ptr) {
890  check_alloc_state();
891  trail_->rev_int64_memory_.push_back(ptr);
892  return ptr;
893 }
894 
895 double* Solver::SafeRevAllocArray(double* ptr) {
896  check_alloc_state();
897  trail_->rev_double_memory_.push_back(ptr);
898  return ptr;
899 }
900 
901 uint64* Solver::SafeRevAllocArray(uint64* ptr) {
902  check_alloc_state();
903  trail_->rev_int64_memory_.push_back(reinterpret_cast<int64*>(ptr));
904  return ptr;
905 }
906 
907 BaseObject** Solver::SafeRevAllocArray(BaseObject** ptr) {
908  check_alloc_state();
909  trail_->rev_object_array_memory_.push_back(ptr);
910  return ptr;
911 }
912 
913 IntVar** Solver::SafeRevAllocArray(IntVar** ptr) {
914  BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
915  return reinterpret_cast<IntVar**>(in);
916 }
917 
918 IntExpr** Solver::SafeRevAllocArray(IntExpr** ptr) {
919  BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
920  return reinterpret_cast<IntExpr**>(in);
921 }
922 
923 Constraint** Solver::SafeRevAllocArray(Constraint** ptr) {
924  BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
925  return reinterpret_cast<Constraint**>(in);
926 }
927 
928 void* Solver::UnsafeRevAllocAux(void* ptr) {
929  check_alloc_state();
930  trail_->rev_memory_.push_back(ptr);
931  return ptr;
932 }
933 
934 void** Solver::UnsafeRevAllocArrayAux(void** ptr) {
935  check_alloc_state();
936  trail_->rev_memory_array_.push_back(ptr);
937  return ptr;
938 }
939 
940 void InternalSaveBooleanVarValue(Solver* const solver, IntVar* const var) {
941  solver->trail_->rev_boolvar_list_.push_back(var);
942 }
943 
944 // ------------------ Search class -----------------
945 
946 class Search {
947  public:
948  explicit Search(Solver* const s)
949  : solver_(s),
950  marker_stack_(),
951  fail_buffer_(),
952  solution_counter_(0),
953  unchecked_solution_counter_(0),
954  decision_builder_(nullptr),
955  created_by_solve_(false),
956  search_depth_(0),
957  left_search_depth_(0),
958  should_restart_(false),
959  should_finish_(false),
960  sentinel_pushed_(0),
961  jmpbuf_filled_(false),
962  backtrack_at_the_end_of_the_search_(true) {}
963 
964  // Constructor for a dummy search. The only difference between a dummy search
965  // and a regular one is that the search depth and left search depth is
966  // initialized to -1 instead of zero.
967  Search(Solver* const s, int /* dummy_argument */)
968  : solver_(s),
969  marker_stack_(),
970  fail_buffer_(),
971  solution_counter_(0),
972  unchecked_solution_counter_(0),
973  decision_builder_(nullptr),
974  created_by_solve_(false),
975  search_depth_(-1),
976  left_search_depth_(-1),
977  should_restart_(false),
978  should_finish_(false),
979  sentinel_pushed_(0),
980  jmpbuf_filled_(false),
981  backtrack_at_the_end_of_the_search_(true) {}
982 
983  ~Search() { gtl::STLDeleteElements(&marker_stack_); }
984 
985  void EnterSearch();
986  void RestartSearch();
987  void ExitSearch();
988  void BeginNextDecision(DecisionBuilder* const db);
989  void EndNextDecision(DecisionBuilder* const db, Decision* const d);
990  void ApplyDecision(Decision* const d);
991  void AfterDecision(Decision* const d, bool apply);
992  void RefuteDecision(Decision* const d);
993  void BeginFail();
994  void EndFail();
996  void EndInitialPropagation();
997  bool AtSolution();
998  bool AcceptSolution();
999  void NoMoreSolutions();
1000  bool LocalOptimum();
1001  bool AcceptDelta(Assignment* delta, Assignment* deltadelta);
1002  void AcceptNeighbor();
1003  void AcceptUncheckedNeighbor();
1005  void PeriodicCheck();
1006  int ProgressPercent();
1007  void Accept(ModelVisitor* const visitor) const;
1008  void push_monitor(SearchMonitor* const m);
1009  void Clear();
1010  void IncrementSolutionCounter() { ++solution_counter_; }
1011  int64 solution_counter() const { return solution_counter_; }
1012  void IncrementUncheckedSolutionCounter() { ++unchecked_solution_counter_; }
1014  return unchecked_solution_counter_;
1015  }
1016  void set_decision_builder(DecisionBuilder* const db) {
1017  decision_builder_ = db;
1018  }
1019  DecisionBuilder* decision_builder() const { return decision_builder_; }
1020  void set_created_by_solve(bool c) { created_by_solve_ = c; }
1021  bool created_by_solve() const { return created_by_solve_; }
1022  Solver::DecisionModification ModifyDecision();
1023  void SetBranchSelector(Solver::BranchSelector bs);
1024  void LeftMove() {
1025  search_depth_++;
1026  left_search_depth_++;
1027  }
1028  void RightMove() { search_depth_++; }
1030  return backtrack_at_the_end_of_the_search_;
1031  }
1033  backtrack_at_the_end_of_the_search_ = restore;
1034  }
1035  int search_depth() const { return search_depth_; }
1036  void set_search_depth(int d) { search_depth_ = d; }
1037  int left_search_depth() const { return left_search_depth_; }
1038  void set_search_left_depth(int d) { left_search_depth_ = d; }
1039  void set_should_restart(bool s) { should_restart_ = s; }
1040  bool should_restart() const { return should_restart_; }
1041  void set_should_finish(bool s) { should_finish_ = s; }
1042  bool should_finish() const { return should_finish_; }
1043  void CheckFail() {
1044  if (should_finish_ || should_restart_) {
1045  solver_->Fail();
1046  }
1047  }
1048  void set_search_context(const std::string& search_context) {
1049  search_context_ = search_context;
1050  }
1051  std::string search_context() const { return search_context_; }
1052  friend class Solver;
1053 
1054  private:
1055  // Jumps back to the previous choice point, Checks if it was correctly set.
1056  void JumpBack();
1057  void ClearBuffer() {
1058  CHECK(jmpbuf_filled_) << "Internal error in backtracking";
1059  jmpbuf_filled_ = false;
1060  }
1061 
1062  Solver* const solver_;
1063  std::vector<StateMarker*> marker_stack_;
1064  std::vector<SearchMonitor*> monitors_;
1065  jmp_buf fail_buffer_;
1066  int64 solution_counter_;
1067  int64 unchecked_solution_counter_;
1068  DecisionBuilder* decision_builder_;
1069  bool created_by_solve_;
1070  Solver::BranchSelector selector_;
1071  int search_depth_;
1072  int left_search_depth_;
1073  bool should_restart_;
1074  bool should_finish_;
1075  int sentinel_pushed_;
1076  bool jmpbuf_filled_;
1077  bool backtrack_at_the_end_of_the_search_;
1078  std::string search_context_;
1079 };
1080 
1081 // Backtrack is implemented using 3 primitives:
1082 // CP_TRY to start searching
1083 // CP_DO_FAIL to signal a failure. The program will continue on the CP_ON_FAIL
1084 // primitive.
1085 // Implementation of backtrack using setjmp/longjmp.
1086 // The clean portable way is to use exceptions, unfortunately, it can be much
1087 // slower. Thus we use ideas from Prolog, CP/CLP implementations,
1088 // continuations in C and implement the default failing and backtracking
1089 // using setjmp/longjmp. You can still use exceptions by defining
1090 // CP_USE_EXCEPTIONS_FOR_BACKTRACK
1091 #ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK
1092 // We cannot use a method/function for this as we would lose the
1093 // context in the setjmp implementation.
1094 #define CP_TRY(search) \
1095  CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1096  search->jmpbuf_filled_ = true; \
1097  if (setjmp(search->fail_buffer_) == 0)
1098 #define CP_ON_FAIL else
1099 #define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1)
1100 #else // CP_USE_EXCEPTIONS_FOR_BACKTRACK
1101 class FailException {};
1102 #define CP_TRY(search) \
1103  CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1104  search->jmpbuf_filled_ = true; \
1105  try
1106 #define CP_ON_FAIL catch (FailException&)
1107 #define CP_DO_FAIL(search) throw FailException()
1108 #endif // CP_USE_EXCEPTIONS_FOR_BACKTRACK
1109 
1110 void Search::JumpBack() {
1111  if (jmpbuf_filled_) {
1112  jmpbuf_filled_ = false;
1113  CP_DO_FAIL(this);
1114  } else {
1115  std::string explanation = "Failure outside of search";
1116  solver_->AddConstraint(solver_->MakeFalseConstraint(explanation));
1117  }
1118 }
1119 
1120 Search* Solver::ActiveSearch() const { return searches_.back(); }
1121 
1122 namespace {
1123 class ApplyBranchSelector : public DecisionBuilder {
1124  public:
1125  explicit ApplyBranchSelector(Solver::BranchSelector bs)
1126  : selector_(std::move(bs)) {}
1127  ~ApplyBranchSelector() override {}
1128 
1129  Decision* Next(Solver* const s) override {
1130  s->SetBranchSelector(selector_);
1131  return nullptr;
1132  }
1133 
1134  std::string DebugString() const override { return "Apply(BranchSelector)"; }
1135 
1136  private:
1137  Solver::BranchSelector const selector_;
1138 };
1139 } // namespace
1140 
1141 void Search::SetBranchSelector(Solver::BranchSelector bs) {
1142  selector_ = std::move(bs);
1143 }
1144 
1145 void Solver::SetBranchSelector(BranchSelector bs) {
1146  // We cannot use the trail as the search can be nested and thus
1147  // deleted upon backtrack. Thus we guard the undo action by a
1148  // check on the number of nesting of solve().
1149  const int solve_depth = SolveDepth();
1150  AddBacktrackAction(
1151  [solve_depth](Solver* s) {
1152  if (s->SolveDepth() == solve_depth) {
1153  s->ActiveSearch()->SetBranchSelector(nullptr);
1154  }
1155  },
1156  false);
1157  searches_.back()->SetBranchSelector(std::move(bs));
1158 }
1159 
1160 DecisionBuilder* Solver::MakeApplyBranchSelector(BranchSelector bs) {
1161  return RevAlloc(new ApplyBranchSelector(std::move(bs)));
1162 }
1163 
1164 int Solver::SolveDepth() const {
1165  return state_ == OUTSIDE_SEARCH ? 0 : searches_.size() - 1;
1166 }
1167 
1168 int Solver::SearchDepth() const { return searches_.back()->search_depth(); }
1169 
1170 int Solver::SearchLeftDepth() const {
1171  return searches_.back()->left_search_depth();
1172 }
1173 
1174 Solver::DecisionModification Search::ModifyDecision() {
1175  if (selector_ != nullptr) {
1176  return selector_();
1177  }
1178  return Solver::NO_CHANGE;
1179 }
1180 
1181 void Search::push_monitor(SearchMonitor* const m) {
1182  if (m) {
1183  monitors_.push_back(m);
1184  }
1185 }
1186 
1188  monitors_.clear();
1189  search_depth_ = 0;
1190  left_search_depth_ = 0;
1191  selector_ = nullptr;
1192  backtrack_at_the_end_of_the_search_ = true;
1193 }
1194 
1196  // The solution counter is reset when entering search and not when
1197  // leaving search. This enables the information to persist outside of
1198  // top-level search.
1199  solution_counter_ = 0;
1200  unchecked_solution_counter_ = 0;
1201 
1202  ForAll(monitors_, &SearchMonitor::EnterSearch);
1203 }
1204 
1206  // Backtrack to the correct state.
1207  ForAll(monitors_, &SearchMonitor::ExitSearch);
1208 }
1209 
1211  ForAll(monitors_, &SearchMonitor::RestartSearch);
1212 }
1213 
1214 void Search::BeginNextDecision(DecisionBuilder* const db) {
1215  ForAll(monitors_, &SearchMonitor::BeginNextDecision, db);
1216  CheckFail();
1217 }
1218 
1219 void Search::EndNextDecision(DecisionBuilder* const db, Decision* const d) {
1220  ForAll(monitors_, &SearchMonitor::EndNextDecision, db, d);
1221  CheckFail();
1222 }
1223 
1224 void Search::ApplyDecision(Decision* const d) {
1225  ForAll(monitors_, &SearchMonitor::ApplyDecision, d);
1226  CheckFail();
1227 }
1228 
1229 void Search::AfterDecision(Decision* const d, bool apply) {
1230  ForAll(monitors_, &SearchMonitor::AfterDecision, d, apply);
1231  CheckFail();
1232 }
1233 
1234 void Search::RefuteDecision(Decision* const d) {
1235  ForAll(monitors_, &SearchMonitor::RefuteDecision, d);
1236  CheckFail();
1237 }
1238 
1239 void Search::BeginFail() { ForAll(monitors_, &SearchMonitor::BeginFail); }
1240 
1241 void Search::EndFail() { ForAll(monitors_, &SearchMonitor::EndFail); }
1242 
1244  ForAll(monitors_, &SearchMonitor::BeginInitialPropagation);
1245 }
1246 
1248  ForAll(monitors_, &SearchMonitor::EndInitialPropagation);
1249 }
1250 
1252  bool valid = true;
1253  for (SearchMonitor* const monitor : monitors_) {
1254  if (!monitor->AcceptSolution()) {
1255  // Even though we know the return value, we cannot return yet: this would
1256  // break the contract we have with solution monitors. They all deserve
1257  // a chance to look at the solution.
1258  valid = false;
1259  }
1260  }
1261  return valid;
1262 }
1263 
1265  bool should_continue = false;
1266  for (SearchMonitor* const monitor : monitors_) {
1267  if (monitor->AtSolution()) {
1268  // Even though we know the return value, we cannot return yet: this would
1269  // break the contract we have with solution monitors. They all deserve
1270  // a chance to look at the solution.
1271  should_continue = true;
1272  }
1273  }
1274  return should_continue;
1275 }
1276 
1278  ForAll(monitors_, &SearchMonitor::NoMoreSolutions);
1279 }
1280 
1282  bool res = false;
1283  for (SearchMonitor* const monitor : monitors_) {
1284  if (monitor->LocalOptimum()) {
1285  res = true;
1286  }
1287  }
1288  return res;
1289 }
1290 
1291 bool Search::AcceptDelta(Assignment* delta, Assignment* deltadelta) {
1292  bool accept = true;
1293  for (SearchMonitor* const monitor : monitors_) {
1294  if (!monitor->AcceptDelta(delta, deltadelta)) {
1295  accept = false;
1296  }
1297  }
1298  return accept;
1299 }
1300 
1302  ForAll(monitors_, &SearchMonitor::AcceptNeighbor);
1303 }
1304 
1306  ForAll(monitors_, &SearchMonitor::AcceptUncheckedNeighbor);
1307 }
1308 
1310  for (SearchMonitor* const monitor : monitors_) {
1311  if (monitor->IsUncheckedSolutionLimitReached()) {
1312  return true;
1313  }
1314  }
1315  return false;
1316 }
1317 
1319  ForAll(monitors_, &SearchMonitor::PeriodicCheck);
1320 }
1321 
1323  int progress = SearchMonitor::kNoProgress;
1324  for (SearchMonitor* const monitor : monitors_) {
1325  progress = std::max(progress, monitor->ProgressPercent());
1326  }
1327  return progress;
1328 }
1329 
1330 void Search::Accept(ModelVisitor* const visitor) const {
1331  ForAll(monitors_, &SearchMonitor::Accept, visitor);
1332  if (decision_builder_ != nullptr) {
1333  decision_builder_->Accept(visitor);
1334  }
1335 }
1336 
1337 bool LocalOptimumReached(Search* const search) {
1338  return search->LocalOptimum();
1339 }
1340 
1341 bool AcceptDelta(Search* const search, Assignment* delta,
1342  Assignment* deltadelta) {
1343  return search->AcceptDelta(delta, deltadelta);
1344 }
1345 
1346 void AcceptNeighbor(Search* const search) { search->AcceptNeighbor(); }
1347 
1348 void AcceptUncheckedNeighbor(Search* const search) {
1349  search->AcceptUncheckedNeighbor();
1350 }
1351 
1352 namespace {
1353 
1354 // ---------- Fail Decision ----------
1355 
1356 class FailDecision : public Decision {
1357  public:
1358  void Apply(Solver* const s) override { s->Fail(); }
1359  void Refute(Solver* const s) override { s->Fail(); }
1360 };
1361 
1362 // Balancing decision
1363 
1364 class BalancingDecision : public Decision {
1365  public:
1366  ~BalancingDecision() override {}
1367  void Apply(Solver* const s) override {}
1368  void Refute(Solver* const s) override {}
1369 };
1370 } // namespace
1371 
1372 Decision* Solver::MakeFailDecision() { return fail_decision_.get(); }
1373 
1374 // ------------------ Solver class -----------------
1375 
1376 // These magic numbers are there to make sure we pop the correct
1377 // sentinels throughout the search.
1378 namespace {
1379 enum SentinelMarker {
1380  INITIAL_SEARCH_SENTINEL = 10000000,
1381  ROOT_NODE_SENTINEL = 20000000,
1382  SOLVER_CTOR_SENTINEL = 40000000
1383 };
1384 } // namespace
1385 
1386 extern PropagationMonitor* BuildTrace(Solver* const s);
1387 extern LocalSearchMonitor* BuildLocalSearchMonitorMaster(Solver* const s);
1388 extern ModelCache* BuildModelCache(Solver* const solver);
1389 
1390 std::string Solver::model_name() const { return name_; }
1391 
1392 namespace {
1393 void CheckSolverParameters(const ConstraintSolverParameters& parameters) {
1394  CHECK_GT(parameters.array_split_size(), 0)
1395  << "Were parameters built using Solver::DefaultSolverParameters() ?";
1396 }
1397 } // namespace
1398 
1399 Solver::Solver(const std::string& name,
1400  const ConstraintSolverParameters& parameters)
1401  : name_(name),
1402  parameters_(parameters),
1403  random_(CpRandomSeed()),
1404  demon_profiler_(BuildDemonProfiler(this)),
1405  use_fast_local_search_(true),
1406  local_search_profiler_(BuildLocalSearchProfiler(this)) {
1407  Init();
1408 }
1409 
1410 Solver::Solver(const std::string& name)
1411  : name_(name),
1412  parameters_(DefaultSolverParameters()),
1413  random_(CpRandomSeed()),
1414  demon_profiler_(BuildDemonProfiler(this)),
1415  use_fast_local_search_(true),
1416  local_search_profiler_(BuildLocalSearchProfiler(this)) {
1417  Init();
1418 }
1419 
1420 void Solver::Init() {
1421  CheckSolverParameters(parameters_);
1422  queue_ = absl::make_unique<Queue>(this);
1423  trail_ = absl::make_unique<Trail>(parameters_.trail_block_size(),
1424  parameters_.compress_trail());
1425  state_ = OUTSIDE_SEARCH;
1426  branches_ = 0;
1427  fails_ = 0;
1428  decisions_ = 0;
1429  neighbors_ = 0;
1430  filtered_neighbors_ = 0;
1431  accepted_neighbors_ = 0;
1432  optimization_direction_ = NOT_SET;
1433  timer_ = absl::make_unique<ClockTimer>();
1434  searches_.assign(1, new Search(this, 0));
1435  fail_stamp_ = GG_ULONGLONG(1);
1436  balancing_decision_ = absl::make_unique<BalancingDecision>();
1437  fail_intercept_ = nullptr;
1438  true_constraint_ = nullptr;
1439  false_constraint_ = nullptr;
1440  fail_decision_ = absl::make_unique<FailDecision>();
1441  constraint_index_ = 0;
1442  additional_constraint_index_ = 0;
1443  num_int_vars_ = 0;
1444  propagation_monitor_.reset(BuildTrace(this));
1445  local_search_monitor_.reset(BuildLocalSearchMonitorMaster(this));
1446  print_trace_ = nullptr;
1447  anonymous_variable_index_ = 0;
1448  should_fail_ = false;
1449 
1450  for (int i = 0; i < kNumPriorities; ++i) {
1451  demon_runs_[i] = 0;
1452  }
1453  searches_.push_back(new Search(this));
1454  PushSentinel(SOLVER_CTOR_SENTINEL);
1455  InitCachedIntConstants(); // to be called after the SENTINEL is set.
1456  InitCachedConstraint(); // Cache the true constraint.
1457  timer_->Restart();
1458  model_cache_.reset(BuildModelCache(this));
1459  AddPropagationMonitor(reinterpret_cast<PropagationMonitor*>(demon_profiler_));
1460  AddLocalSearchMonitor(
1461  reinterpret_cast<LocalSearchMonitor*>(local_search_profiler_));
1462 }
1463 
1464 Solver::~Solver() {
1465  // solver destructor called with searches open.
1466  CHECK_EQ(2, searches_.size());
1467  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1468 
1469  StateInfo info;
1470  Solver::MarkerType finalType = PopState(&info);
1471  // Not popping a SENTINEL in Solver destructor.
1472  DCHECK_EQ(finalType, SENTINEL);
1473  // Not popping initial SENTINEL in Solver destructor.
1474  DCHECK_EQ(info.int_info, SOLVER_CTOR_SENTINEL);
1475  gtl::STLDeleteElements(&searches_);
1476  DeleteDemonProfiler(demon_profiler_);
1477  DeleteLocalSearchProfiler(local_search_profiler_);
1478 }
1479 
1480 std::string Solver::DebugString() const {
1481  std::string out = "Solver(name = \"" + name_ + "\", state = ";
1482  switch (state_) {
1483  case OUTSIDE_SEARCH:
1484  out += "OUTSIDE_SEARCH";
1485  break;
1486  case IN_ROOT_NODE:
1487  out += "IN_ROOT_NODE";
1488  break;
1489  case IN_SEARCH:
1490  out += "IN_SEARCH";
1491  break;
1492  case AT_SOLUTION:
1493  out += "AT_SOLUTION";
1494  break;
1495  case NO_MORE_SOLUTIONS:
1496  out += "NO_MORE_SOLUTIONS";
1497  break;
1498  case PROBLEM_INFEASIBLE:
1499  out += "PROBLEM_INFEASIBLE";
1500  break;
1501  }
1502  absl::StrAppendFormat(
1503  &out,
1504  ", branches = %d, fails = %d, decisions = %d, delayed demon runs = %d, "
1505  "var demon runs = %d, normal demon runs = %d, Run time = %d ms)",
1506  branches_, fails_, decisions_, demon_runs_[DELAYED_PRIORITY],
1507  demon_runs_[VAR_PRIORITY], demon_runs_[NORMAL_PRIORITY], wall_time());
1508  return out;
1509 }
1510 
1512 
1513 int64 Solver::wall_time() const {
1514  return absl::ToInt64Milliseconds(timer_->GetDuration());
1515 }
1516 
1517 absl::Time Solver::Now() const {
1518  return absl::FromUnixSeconds(0) + timer_->GetDuration();
1519 }
1520 
1521 int64 Solver::solutions() const { return TopLevelSearch()->solution_counter(); }
1522 
1523 int64 Solver::unchecked_solutions() const {
1524  return TopLevelSearch()->unchecked_solution_counter();
1525 }
1526 
1527 void Solver::IncrementUncheckedSolutionCounter() {
1528  TopLevelSearch()->IncrementUncheckedSolutionCounter();
1529 }
1530 
1531 bool Solver::IsUncheckedSolutionLimitReached() {
1532  return TopLevelSearch()->IsUncheckedSolutionLimitReached();
1533 }
1534 
1535 void Solver::TopPeriodicCheck() { TopLevelSearch()->PeriodicCheck(); }
1536 
1537 int Solver::TopProgressPercent() { return TopLevelSearch()->ProgressPercent(); }
1538 
1539 void Solver::PushState() {
1540  StateInfo info;
1541  PushState(SIMPLE_MARKER, info);
1542 }
1543 
1544 void Solver::PopState() {
1545  StateInfo info;
1546  Solver::MarkerType t = PopState(&info);
1547  CHECK_EQ(SIMPLE_MARKER, t);
1548 }
1549 
1550 void Solver::PushState(Solver::MarkerType t, const StateInfo& info) {
1551  StateMarker* m = new StateMarker(t, info);
1552  if (t != REVERSIBLE_ACTION || info.int_info == 0) {
1553  m->rev_int_index_ = trail_->rev_ints_.size();
1554  m->rev_int64_index_ = trail_->rev_int64s_.size();
1555  m->rev_uint64_index_ = trail_->rev_uint64s_.size();
1556  m->rev_double_index_ = trail_->rev_doubles_.size();
1557  m->rev_ptr_index_ = trail_->rev_ptrs_.size();
1558  m->rev_boolvar_list_index_ = trail_->rev_boolvar_list_.size();
1559  m->rev_bools_index_ = trail_->rev_bools_.size();
1560  m->rev_int_memory_index_ = trail_->rev_int_memory_.size();
1561  m->rev_int64_memory_index_ = trail_->rev_int64_memory_.size();
1562  m->rev_double_memory_index_ = trail_->rev_double_memory_.size();
1563  m->rev_object_memory_index_ = trail_->rev_object_memory_.size();
1564  m->rev_object_array_memory_index_ = trail_->rev_object_array_memory_.size();
1565  m->rev_memory_index_ = trail_->rev_memory_.size();
1566  m->rev_memory_array_index_ = trail_->rev_memory_array_.size();
1567  }
1568  searches_.back()->marker_stack_.push_back(m);
1569  queue_->increase_stamp();
1570 }
1571 
1572 void Solver::AddBacktrackAction(Action a, bool fast) {
1573  StateInfo info(std::move(a), fast);
1574  PushState(REVERSIBLE_ACTION, info);
1575 }
1576 
1577 Solver::MarkerType Solver::PopState(StateInfo* info) {
1578  CHECK(!searches_.back()->marker_stack_.empty())
1579  << "PopState() on an empty stack";
1580  CHECK(info != nullptr);
1581  StateMarker* const m = searches_.back()->marker_stack_.back();
1582  if (m->type_ != REVERSIBLE_ACTION || m->info_.int_info == 0) {
1583  trail_->BacktrackTo(m);
1584  }
1585  Solver::MarkerType t = m->type_;
1586  (*info) = m->info_;
1587  searches_.back()->marker_stack_.pop_back();
1588  delete m;
1589  queue_->increase_stamp();
1590  return t;
1591 }
1592 
1593 void Solver::check_alloc_state() {
1594  switch (state_) {
1595  case OUTSIDE_SEARCH:
1596  case IN_ROOT_NODE:
1597  case IN_SEARCH:
1598  case NO_MORE_SOLUTIONS:
1599  case PROBLEM_INFEASIBLE:
1600  break;
1601  case AT_SOLUTION:
1602  LOG(FATAL) << "allocating at a leaf node";
1603  default:
1604  LOG(FATAL) << "This switch was supposed to be exhaustive, but it is not!";
1605  }
1606 }
1607 
1608 void Solver::FreezeQueue() { queue_->Freeze(); }
1609 
1610 void Solver::UnfreezeQueue() { queue_->Unfreeze(); }
1611 
1612 void Solver::EnqueueVar(Demon* const d) { queue_->EnqueueVar(d); }
1613 
1614 void Solver::EnqueueDelayedDemon(Demon* const d) {
1615  queue_->EnqueueDelayedDemon(d);
1616 }
1617 
1618 void Solver::ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
1619  queue_->ExecuteAll(demons);
1620 }
1621 
1622 void Solver::EnqueueAll(const SimpleRevFIFO<Demon*>& demons) {
1623  queue_->EnqueueAll(demons);
1624 }
1625 
1626 uint64 Solver::stamp() const { return queue_->stamp(); }
1627 
1628 uint64 Solver::fail_stamp() const { return fail_stamp_; }
1629 
1630 void Solver::set_action_on_fail(Action a) {
1631  queue_->set_action_on_fail(std::move(a));
1632 }
1633 
1634 void Solver::set_variable_to_clean_on_fail(IntVar* v) {
1635  queue_->set_variable_to_clean_on_fail(v);
1636 }
1637 
1638 void Solver::reset_action_on_fail() { queue_->reset_action_on_fail(); }
1639 
1640 void Solver::AddConstraint(Constraint* const c) {
1641  DCHECK(c != nullptr);
1642  if (c == true_constraint_) {
1643  return;
1644  }
1645  if (state_ == IN_SEARCH) {
1646  queue_->AddConstraint(c);
1647  } else if (state_ == IN_ROOT_NODE) {
1648  DCHECK_GE(constraint_index_, 0);
1649  DCHECK_LE(constraint_index_, constraints_list_.size());
1650  const int constraint_parent =
1651  constraint_index_ == constraints_list_.size()
1652  ? additional_constraints_parent_list_[additional_constraint_index_]
1653  : constraint_index_;
1654  additional_constraints_list_.push_back(c);
1655  additional_constraints_parent_list_.push_back(constraint_parent);
1656  } else {
1657  if (parameters_.print_added_constraints()) {
1658  LOG(INFO) << c->DebugString();
1659  }
1660  constraints_list_.push_back(c);
1661  }
1662 }
1663 
1664 void Solver::AddCastConstraint(CastConstraint* const constraint,
1665  IntVar* const target_var, IntExpr* const expr) {
1666  if (constraint != nullptr) {
1667  if (state_ != IN_SEARCH) {
1668  cast_constraints_.insert(constraint);
1669  cast_information_[target_var] =
1670  Solver::IntegerCastInfo(target_var, expr, constraint);
1671  }
1672  AddConstraint(constraint);
1673  }
1674 }
1675 
1676 void Solver::Accept(ModelVisitor* const visitor) const {
1677  visitor->BeginVisitModel(name_);
1678  ForAll(constraints_list_, &Constraint::Accept, visitor);
1679  visitor->EndVisitModel(name_);
1680 }
1681 
1682 void Solver::ProcessConstraints() {
1683  // Both constraints_list_ and additional_constraints_list_ are used in
1684  // a FIFO way.
1685  if (parameters_.print_model()) {
1686  ModelVisitor* const visitor = MakePrintModelVisitor();
1687  Accept(visitor);
1688  }
1689  if (parameters_.print_model_stats()) {
1690  ModelVisitor* const visitor = MakeStatisticsModelVisitor();
1691  Accept(visitor);
1692  }
1693 
1694  if (parameters_.disable_solve()) {
1695  LOG(INFO) << "Forcing early failure";
1696  Fail();
1697  }
1698 
1699  // Clear state before processing constraints.
1700  const int constraints_size = constraints_list_.size();
1701  additional_constraints_list_.clear();
1702  additional_constraints_parent_list_.clear();
1703 
1704  for (constraint_index_ = 0; constraint_index_ < constraints_size;
1705  ++constraint_index_) {
1706  Constraint* const constraint = constraints_list_[constraint_index_];
1707  propagation_monitor_->BeginConstraintInitialPropagation(constraint);
1708  constraint->PostAndPropagate();
1709  propagation_monitor_->EndConstraintInitialPropagation(constraint);
1710  }
1711  CHECK_EQ(constraints_list_.size(), constraints_size);
1712 
1713  // Process nested constraints added during the previous step.
1714  for (int additional_constraint_index_ = 0;
1715  additional_constraint_index_ < additional_constraints_list_.size();
1716  ++additional_constraint_index_) {
1717  Constraint* const nested =
1718  additional_constraints_list_[additional_constraint_index_];
1719  const int parent_index =
1720  additional_constraints_parent_list_[additional_constraint_index_];
1721  Constraint* const parent = constraints_list_[parent_index];
1722  propagation_monitor_->BeginNestedConstraintInitialPropagation(parent,
1723  nested);
1724  nested->PostAndPropagate();
1725  propagation_monitor_->EndNestedConstraintInitialPropagation(parent, nested);
1726  }
1727 }
1728 
1729 bool Solver::CurrentlyInSolve() const {
1730  DCHECK_GT(SolveDepth(), 0);
1731  DCHECK(searches_.back() != nullptr);
1732  return searches_.back()->created_by_solve();
1733 }
1734 
1735 bool Solver::Solve(DecisionBuilder* const db, SearchMonitor* const m1) {
1736  std::vector<SearchMonitor*> monitors;
1737  monitors.push_back(m1);
1738  return Solve(db, monitors);
1739 }
1740 
1741 bool Solver::Solve(DecisionBuilder* const db) {
1742  std::vector<SearchMonitor*> monitors;
1743  return Solve(db, monitors);
1744 }
1745 
1746 bool Solver::Solve(DecisionBuilder* const db, SearchMonitor* const m1,
1747  SearchMonitor* const m2) {
1748  std::vector<SearchMonitor*> monitors;
1749  monitors.push_back(m1);
1750  monitors.push_back(m2);
1751  return Solve(db, monitors);
1752 }
1753 
1754 bool Solver::Solve(DecisionBuilder* const db, SearchMonitor* const m1,
1755  SearchMonitor* const m2, SearchMonitor* const m3) {
1756  std::vector<SearchMonitor*> monitors;
1757  monitors.push_back(m1);
1758  monitors.push_back(m2);
1759  monitors.push_back(m3);
1760  return Solve(db, monitors);
1761 }
1762 
1763 bool Solver::Solve(DecisionBuilder* const db, SearchMonitor* const m1,
1764  SearchMonitor* const m2, SearchMonitor* const m3,
1765  SearchMonitor* const m4) {
1766  std::vector<SearchMonitor*> monitors;
1767  monitors.push_back(m1);
1768  monitors.push_back(m2);
1769  monitors.push_back(m3);
1770  monitors.push_back(m4);
1771  return Solve(db, monitors);
1772 }
1773 
1774 bool Solver::Solve(DecisionBuilder* const db,
1775  const std::vector<SearchMonitor*>& monitors) {
1776  NewSearch(db, monitors);
1777  searches_.back()->set_created_by_solve(true); // Overwrites default.
1778  NextSolution();
1779  const bool solution_found = searches_.back()->solution_counter() > 0;
1780  EndSearch();
1781  return solution_found;
1782 }
1783 
1784 void Solver::NewSearch(DecisionBuilder* const db, SearchMonitor* const m1) {
1785  std::vector<SearchMonitor*> monitors;
1786  monitors.push_back(m1);
1787  return NewSearch(db, monitors);
1788 }
1789 
1790 void Solver::NewSearch(DecisionBuilder* const db) {
1791  std::vector<SearchMonitor*> monitors;
1792  return NewSearch(db, monitors);
1793 }
1794 
1795 void Solver::NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
1796  SearchMonitor* const m2) {
1797  std::vector<SearchMonitor*> monitors;
1798  monitors.push_back(m1);
1799  monitors.push_back(m2);
1800  return NewSearch(db, monitors);
1801 }
1802 
1803 void Solver::NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
1804  SearchMonitor* const m2, SearchMonitor* const m3) {
1805  std::vector<SearchMonitor*> monitors;
1806  monitors.push_back(m1);
1807  monitors.push_back(m2);
1808  monitors.push_back(m3);
1809  return NewSearch(db, monitors);
1810 }
1811 
1812 void Solver::NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
1813  SearchMonitor* const m2, SearchMonitor* const m3,
1814  SearchMonitor* const m4) {
1815  std::vector<SearchMonitor*> monitors;
1816  monitors.push_back(m1);
1817  monitors.push_back(m2);
1818  monitors.push_back(m3);
1819  monitors.push_back(m4);
1820  return NewSearch(db, monitors);
1821 }
1822 
1823 extern PropagationMonitor* BuildPrintTrace(Solver* const s);
1824 
1825 // Opens a new top level search.
1826 void Solver::NewSearch(DecisionBuilder* const db,
1827  const std::vector<SearchMonitor*>& monitors) {
1828  // TODO(user) : reset statistics
1829 
1830  CHECK(db != nullptr);
1831  const bool nested = state_ == IN_SEARCH;
1832 
1833  if (state_ == IN_ROOT_NODE) {
1834  LOG(FATAL) << "Cannot start new searches here.";
1835  }
1836 
1837  Search* const search = nested ? new Search(this) : searches_.back();
1838  search->set_created_by_solve(false); // default behavior.
1839 
1840  // ----- jumps to correct state -----
1841 
1842  if (nested) {
1843  // Nested searches are created on demand, and deleted afterwards.
1844  DCHECK_GE(searches_.size(), 2);
1845  searches_.push_back(search);
1846  } else {
1847  // Top level search is persistent.
1848  // TODO(user): delete top level search after EndSearch().
1849  DCHECK_EQ(2, searches_.size());
1850  // TODO(user): Check if these two lines are still necessary.
1851  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1852  state_ = OUTSIDE_SEARCH;
1853  }
1854 
1855  // ----- manages all monitors -----
1856 
1857  // Always install the main propagation and local search monitors.
1858  propagation_monitor_->Install();
1859  if (demon_profiler_ != nullptr) {
1860  InstallDemonProfiler(demon_profiler_);
1861  }
1862  local_search_monitor_->Install();
1863  if (local_search_profiler_ != nullptr) {
1864  InstallLocalSearchProfiler(local_search_profiler_);
1865  }
1866 
1867  // Push monitors and enter search.
1868  for (SearchMonitor* const monitor : monitors) {
1869  if (monitor != nullptr) {
1870  monitor->Install();
1871  }
1872  }
1873  std::vector<SearchMonitor*> extras;
1874  db->AppendMonitors(this, &extras);
1875  for (SearchMonitor* const monitor : extras) {
1876  if (monitor != nullptr) {
1877  monitor->Install();
1878  }
1879  }
1880  // Install the print trace if needed.
1881  // The print_trace needs to be last to detect propagation from the objective.
1882  if (nested) {
1883  if (print_trace_ != nullptr) { // Was installed at the top level?
1884  print_trace_->Install(); // Propagates to nested search.
1885  }
1886  } else { // Top level search
1887  print_trace_ = nullptr; // Clears it first.
1888  if (parameters_.trace_propagation()) {
1889  print_trace_ = BuildPrintTrace(this);
1890  print_trace_->Install();
1891  } else if (parameters_.trace_search()) {
1892  // This is useful to trace the exact behavior of the search.
1893  // The '######## ' prefix is the same as the progagation trace.
1894  // Search trace is subsumed by propagation trace, thus only one
1895  // is necessary.
1896  SearchMonitor* const trace = MakeSearchTrace("######## ");
1897  trace->Install();
1898  }
1899  }
1900 
1901  // ----- enters search -----
1902 
1903  search->EnterSearch();
1904 
1905  // Push sentinel and set decision builder.
1906  PushSentinel(INITIAL_SEARCH_SENTINEL);
1907  search->set_decision_builder(db);
1908 }
1909 
1910 // Backtrack to the last open right branch in the search tree.
1911 // It returns true in case the search tree has been completely explored.
1912 bool Solver::BacktrackOneLevel(Decision** const fail_decision) {
1913  bool no_more_solutions = false;
1914  bool end_loop = false;
1915  while (!end_loop) {
1916  StateInfo info;
1917  Solver::MarkerType t = PopState(&info);
1918  switch (t) {
1919  case SENTINEL:
1920  CHECK_EQ(info.ptr_info, this) << "Wrong sentinel found";
1921  CHECK((info.int_info == ROOT_NODE_SENTINEL && SolveDepth() == 1) ||
1922  (info.int_info == INITIAL_SEARCH_SENTINEL && SolveDepth() > 1));
1923  searches_.back()->sentinel_pushed_--;
1924  no_more_solutions = true;
1925  end_loop = true;
1926  break;
1927  case SIMPLE_MARKER:
1928  LOG(ERROR) << "Simple markers should not be encountered during search";
1929  break;
1930  case CHOICE_POINT:
1931  if (info.int_info == 0) { // was left branch
1932  (*fail_decision) = reinterpret_cast<Decision*>(info.ptr_info);
1933  end_loop = true;
1934  searches_.back()->set_search_depth(info.depth);
1935  searches_.back()->set_search_left_depth(info.left_depth);
1936  }
1937  break;
1938  case REVERSIBLE_ACTION: {
1939  if (info.reversible_action != nullptr) {
1940  info.reversible_action(this);
1941  }
1942  break;
1943  }
1944  }
1945  }
1946  Search* const search = searches_.back();
1947  search->EndFail();
1948  fail_stamp_++;
1949  if (no_more_solutions) {
1950  search->NoMoreSolutions();
1951  }
1952  return no_more_solutions;
1953 }
1954 
1955 void Solver::PushSentinel(int magic_code) {
1956  StateInfo info(this, magic_code);
1957  PushState(SENTINEL, info);
1958  // We do not count the sentinel pushed in the ctor.
1959  if (magic_code != SOLVER_CTOR_SENTINEL) {
1960  searches_.back()->sentinel_pushed_++;
1961  }
1962  const int pushed = searches_.back()->sentinel_pushed_;
1963  DCHECK((magic_code == SOLVER_CTOR_SENTINEL) ||
1964  (magic_code == INITIAL_SEARCH_SENTINEL && pushed == 1) ||
1965  (magic_code == ROOT_NODE_SENTINEL && pushed == 2));
1966 }
1967 
1968 void Solver::RestartSearch() {
1969  Search* const search = searches_.back();
1970  CHECK_NE(0, search->sentinel_pushed_);
1971  if (SolveDepth() == 1) { // top level.
1972  if (search->sentinel_pushed_ > 1) {
1973  BacktrackToSentinel(ROOT_NODE_SENTINEL);
1974  }
1975  CHECK_EQ(1, search->sentinel_pushed_);
1976  PushSentinel(ROOT_NODE_SENTINEL);
1977  state_ = IN_SEARCH;
1978  } else {
1979  CHECK_EQ(IN_SEARCH, state_);
1980  if (search->sentinel_pushed_ > 0) {
1981  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1982  }
1983  CHECK_EQ(0, search->sentinel_pushed_);
1984  PushSentinel(INITIAL_SEARCH_SENTINEL);
1985  }
1986 
1987  search->RestartSearch();
1988 }
1989 
1990 // Backtrack to the initial search sentinel.
1991 // Does not change the state, this should be done by the caller.
1992 void Solver::BacktrackToSentinel(int magic_code) {
1993  Search* const search = searches_.back();
1994  bool end_loop = search->sentinel_pushed_ == 0;
1995  while (!end_loop) {
1996  StateInfo info;
1997  Solver::MarkerType t = PopState(&info);
1998  switch (t) {
1999  case SENTINEL: {
2000  CHECK_EQ(info.ptr_info, this) << "Wrong sentinel found";
2001  CHECK_GE(--search->sentinel_pushed_, 0);
2002  search->set_search_depth(0);
2003  search->set_search_left_depth(0);
2004 
2005  if (info.int_info == magic_code) {
2006  end_loop = true;
2007  }
2008  break;
2009  }
2010  case SIMPLE_MARKER:
2011  break;
2012  case CHOICE_POINT:
2013  break;
2014  case REVERSIBLE_ACTION: {
2015  info.reversible_action(this);
2016  break;
2017  }
2018  }
2019  }
2020  fail_stamp_++;
2021 }
2022 
2023 // Closes the current search without backtrack.
2024 void Solver::JumpToSentinelWhenNested() {
2025  CHECK_GT(SolveDepth(), 1) << "calling JumpToSentinel from top level";
2026  Search* c = searches_.back();
2027  Search* p = ParentSearch();
2028  bool found = false;
2029  while (!c->marker_stack_.empty()) {
2030  StateMarker* const m = c->marker_stack_.back();
2031  if (m->type_ == REVERSIBLE_ACTION) {
2032  p->marker_stack_.push_back(m);
2033  } else {
2034  if (m->type_ == SENTINEL) {
2035  CHECK_EQ(c->marker_stack_.size(), 1) << "Sentinel found too early";
2036  found = true;
2037  }
2038  delete m;
2039  }
2040  c->marker_stack_.pop_back();
2041  }
2042  c->set_search_depth(0);
2043  c->set_search_left_depth(0);
2044  CHECK_EQ(found, true) << "Sentinel not found";
2045 }
2046 
2047 namespace {
2048 class ReverseDecision : public Decision {
2049  public:
2050  explicit ReverseDecision(Decision* const d) : decision_(d) {
2051  CHECK(d != nullptr);
2052  }
2053  ~ReverseDecision() override {}
2054 
2055  void Apply(Solver* const s) override { decision_->Refute(s); }
2056 
2057  void Refute(Solver* const s) override { decision_->Apply(s); }
2058 
2059  void Accept(DecisionVisitor* const visitor) const override {
2060  decision_->Accept(visitor);
2061  }
2062 
2063  std::string DebugString() const override {
2064  std::string str = "Reverse(";
2065  str += decision_->DebugString();
2066  str += ")";
2067  return str;
2068  }
2069 
2070  private:
2071  Decision* const decision_;
2072 };
2073 } // namespace
2074 
2075 // Search for the next solution in the search tree.
2076 bool Solver::NextSolution() {
2077  Search* const search = searches_.back();
2078  Decision* fd = nullptr;
2079  const int solve_depth = SolveDepth();
2080  const bool top_level = solve_depth <= 1;
2081 
2082  if (solve_depth == 0 && !search->decision_builder()) {
2083  LOG(WARNING) << "NextSolution() called without a NewSearch before";
2084  return false;
2085  }
2086 
2087  if (top_level) { // Manage top level state.
2088  switch (state_) {
2089  case PROBLEM_INFEASIBLE:
2090  return false;
2091  case NO_MORE_SOLUTIONS:
2092  return false;
2093  case AT_SOLUTION: {
2094  if (BacktrackOneLevel(&fd)) { // No more solutions.
2095  state_ = NO_MORE_SOLUTIONS;
2096  return false;
2097  }
2098  state_ = IN_SEARCH;
2099  break;
2100  }
2101  case OUTSIDE_SEARCH: {
2102  state_ = IN_ROOT_NODE;
2103  search->BeginInitialPropagation();
2104  CP_TRY(search) {
2105  ProcessConstraints();
2106  search->EndInitialPropagation();
2107  PushSentinel(ROOT_NODE_SENTINEL);
2108  state_ = IN_SEARCH;
2109  search->ClearBuffer();
2110  }
2111  CP_ON_FAIL {
2112  queue_->AfterFailure();
2113  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2114  state_ = PROBLEM_INFEASIBLE;
2115  return false;
2116  }
2117  break;
2118  }
2119  case IN_SEARCH: // Usually after a RestartSearch
2120  break;
2121  case IN_ROOT_NODE:
2122  LOG(FATAL) << "Should not happen";
2123  break;
2124  }
2125  }
2126 
2127  volatile bool finish = false;
2128  volatile bool result = false;
2129  DecisionBuilder* const db = search->decision_builder();
2130 
2131  while (!finish) {
2132  CP_TRY(search) {
2133  if (fd != nullptr) {
2134  StateInfo i1(fd, 1, search->search_depth(),
2135  search->left_search_depth()); // 1 for right branch
2136  PushState(CHOICE_POINT, i1);
2137  search->RefuteDecision(fd);
2138  branches_++;
2139  fd->Refute(this);
2140  // Check the fail state that could have been set in the python/java/C#
2141  // layer.
2142  CheckFail();
2143  search->AfterDecision(fd, false);
2144  search->RightMove();
2145  fd = nullptr;
2146  }
2147  Decision* d = nullptr;
2148  for (;;) {
2149  search->BeginNextDecision(db);
2150  d = db->Next(this);
2151  search->EndNextDecision(db, d);
2152  if (d == fail_decision_.get()) {
2153  Fail(); // fail now instead of after 2 branches.
2154  }
2155  if (d != nullptr) {
2156  DecisionModification modification = search->ModifyDecision();
2157  switch (modification) {
2158  case SWITCH_BRANCHES: {
2159  d = RevAlloc(new ReverseDecision(d));
2160  // We reverse the decision and fall through the normal code.
2161  ABSL_FALLTHROUGH_INTENDED;
2162  }
2163  case NO_CHANGE: {
2164  decisions_++;
2165  StateInfo i2(d, 0, search->search_depth(),
2166  search->left_search_depth()); // 0 for left branch
2167  PushState(CHOICE_POINT, i2);
2168  search->ApplyDecision(d);
2169  branches_++;
2170  d->Apply(this);
2171  CheckFail();
2172  search->AfterDecision(d, true);
2173  search->LeftMove();
2174  break;
2175  }
2176  case KEEP_LEFT: {
2177  search->ApplyDecision(d);
2178  d->Apply(this);
2179  CheckFail();
2180  search->AfterDecision(d, true);
2181  break;
2182  }
2183  case KEEP_RIGHT: {
2184  search->RefuteDecision(d);
2185  d->Refute(this);
2186  CheckFail();
2187  search->AfterDecision(d, false);
2188  break;
2189  }
2190  case KILL_BOTH: {
2191  Fail();
2192  }
2193  }
2194  } else {
2195  break;
2196  }
2197  }
2198  if (search->AcceptSolution()) {
2199  search->IncrementSolutionCounter();
2200  if (!search->AtSolution() || !CurrentlyInSolve()) {
2201  result = true;
2202  finish = true;
2203  } else {
2204  Fail();
2205  }
2206  } else {
2207  Fail();
2208  }
2209  }
2210  CP_ON_FAIL {
2211  queue_->AfterFailure();
2212  if (search->should_finish()) {
2213  fd = nullptr;
2214  BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2215  : INITIAL_SEARCH_SENTINEL);
2216  result = false;
2217  finish = true;
2218  search->set_should_finish(false);
2219  search->set_should_restart(false);
2220  // We do not need to push back the sentinel as we are exiting anyway.
2221  } else if (search->should_restart()) {
2222  fd = nullptr;
2223  BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2224  : INITIAL_SEARCH_SENTINEL);
2225  search->set_should_finish(false);
2226  search->set_should_restart(false);
2227  PushSentinel(top_level ? ROOT_NODE_SENTINEL : INITIAL_SEARCH_SENTINEL);
2228  search->RestartSearch();
2229  } else {
2230  if (BacktrackOneLevel(&fd)) { // no more solutions.
2231  result = false;
2232  finish = true;
2233  }
2234  }
2235  }
2236  }
2237  if (result) {
2238  search->ClearBuffer();
2239  }
2240  if (top_level) { // Manage state after NextSolution().
2241  state_ = (result ? AT_SOLUTION : NO_MORE_SOLUTIONS);
2242  }
2243  return result;
2244 }
2245 
2246 void Solver::EndSearch() {
2247  Search* const search = searches_.back();
2248  if (search->backtrack_at_the_end_of_the_search()) {
2249  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2250  } else {
2251  CHECK_GT(searches_.size(), 2);
2252  if (search->sentinel_pushed_ > 0) {
2253  JumpToSentinelWhenNested();
2254  }
2255  }
2256  search->ExitSearch();
2257  search->Clear();
2258  if (2 == searches_.size()) { // Ending top level search.
2259  // Restores the state.
2260  state_ = OUTSIDE_SEARCH;
2261  // Checks if we want to export the profile info.
2262  if (!parameters_.profile_file().empty()) {
2263  const std::string& file_name = parameters_.profile_file();
2264  LOG(INFO) << "Exporting profile to " << file_name;
2265  ExportProfilingOverview(file_name);
2266  }
2267  if (parameters_.print_local_search_profile()) {
2268  LOG(INFO) << LocalSearchProfile();
2269  }
2270  } else { // We clean the nested Search.
2271  delete search;
2272  searches_.pop_back();
2273  }
2274 }
2275 
2276 bool Solver::CheckAssignment(Assignment* const solution) {
2277  CHECK(solution);
2278  if (state_ == IN_SEARCH || state_ == IN_ROOT_NODE) {
2279  LOG(FATAL) << "CheckAssignment is only available at the top level.";
2280  }
2281  // Check state and go to OUTSIDE_SEARCH.
2282  Search* const search = searches_.back();
2283  search->set_created_by_solve(false); // default behavior.
2284 
2285  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2286  state_ = OUTSIDE_SEARCH;
2287 
2288  // Push monitors and enter search.
2289  search->EnterSearch();
2290 
2291  // Push sentinel and set decision builder.
2292  DCHECK_EQ(0, SolveDepth());
2293  DCHECK_EQ(2, searches_.size());
2294  PushSentinel(INITIAL_SEARCH_SENTINEL);
2295  search->BeginInitialPropagation();
2296  CP_TRY(search) {
2297  state_ = IN_ROOT_NODE;
2298  DecisionBuilder* const restore = MakeRestoreAssignment(solution);
2299  restore->Next(this);
2300  ProcessConstraints();
2301  search->EndInitialPropagation();
2302  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2303  search->ClearBuffer();
2304  state_ = OUTSIDE_SEARCH;
2305  return true;
2306  }
2307  CP_ON_FAIL {
2308  const int index =
2309  constraint_index_ < constraints_list_.size()
2310  ? constraint_index_
2311  : additional_constraints_parent_list_[additional_constraint_index_];
2312  Constraint* const ct = constraints_list_[index];
2313  if (ct->name().empty()) {
2314  LOG(INFO) << "Failing constraint = " << ct->DebugString();
2315  } else {
2316  LOG(INFO) << "Failing constraint = " << ct->name() << ":"
2317  << ct->DebugString();
2318  }
2319  queue_->AfterFailure();
2320  BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2321  state_ = PROBLEM_INFEASIBLE;
2322  return false;
2323  }
2324 }
2325 
2326 namespace {
2327 class AddConstraintDecisionBuilder : public DecisionBuilder {
2328  public:
2329  explicit AddConstraintDecisionBuilder(Constraint* const ct)
2330  : constraint_(ct) {
2331  CHECK(ct != nullptr);
2332  }
2333 
2334  ~AddConstraintDecisionBuilder() override {}
2335 
2336  Decision* Next(Solver* const solver) override {
2337  solver->AddConstraint(constraint_);
2338  return nullptr;
2339  }
2340 
2341  std::string DebugString() const override {
2342  return absl::StrFormat("AddConstraintDecisionBuilder(%s)",
2343  constraint_->DebugString());
2344  }
2345 
2346  private:
2347  Constraint* const constraint_;
2348 };
2349 } // namespace
2350 
2351 DecisionBuilder* Solver::MakeConstraintAdder(Constraint* const ct) {
2352  return RevAlloc(new AddConstraintDecisionBuilder(ct));
2353 }
2354 
2355 bool Solver::CheckConstraint(Constraint* const ct) {
2356  return Solve(MakeConstraintAdder(ct));
2357 }
2358 
2359 bool Solver::SolveAndCommit(DecisionBuilder* const db,
2360  SearchMonitor* const m1) {
2361  std::vector<SearchMonitor*> monitors;
2362  monitors.push_back(m1);
2363  return SolveAndCommit(db, monitors);
2364 }
2365 
2366 bool Solver::SolveAndCommit(DecisionBuilder* const db) {
2367  std::vector<SearchMonitor*> monitors;
2368  return SolveAndCommit(db, monitors);
2369 }
2370 
2371 bool Solver::SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1,
2372  SearchMonitor* const m2) {
2373  std::vector<SearchMonitor*> monitors;
2374  monitors.push_back(m1);
2375  monitors.push_back(m2);
2376  return SolveAndCommit(db, monitors);
2377 }
2378 
2379 bool Solver::SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1,
2380  SearchMonitor* const m2, SearchMonitor* const m3) {
2381  std::vector<SearchMonitor*> monitors;
2382  monitors.push_back(m1);
2383  monitors.push_back(m2);
2384  monitors.push_back(m3);
2385  return SolveAndCommit(db, monitors);
2386 }
2387 
2388 bool Solver::SolveAndCommit(DecisionBuilder* const db,
2389  const std::vector<SearchMonitor*>& monitors) {
2390  NewSearch(db, monitors);
2391  searches_.back()->set_created_by_solve(true); // Overwrites default.
2392  searches_.back()->set_backtrack_at_the_end_of_the_search(false);
2393  NextSolution();
2394  const bool solution_found = searches_.back()->solution_counter() > 0;
2395  EndSearch();
2396  return solution_found;
2397 }
2398 
2399 void Solver::Fail() {
2400  if (fail_intercept_) {
2401  fail_intercept_();
2402  return;
2403  }
2405  fails_++;
2406  searches_.back()->BeginFail();
2407  searches_.back()->JumpBack();
2408 }
2409 
2410 void Solver::FinishCurrentSearch() {
2411  searches_.back()->set_should_finish(true);
2412 }
2413 
2414 void Solver::RestartCurrentSearch() {
2415  searches_.back()->set_should_restart(true);
2416 }
2417 
2418 // ----- Cast Expression -----
2419 
2420 IntExpr* Solver::CastExpression(const IntVar* const var) const {
2421  const IntegerCastInfo* const cast_info =
2422  gtl::FindOrNull(cast_information_, var);
2423  if (cast_info != nullptr) {
2424  return cast_info->expression;
2425  }
2426  return nullptr;
2427 }
2428 
2429 // --- Propagation object names ---
2430 
2431 std::string Solver::GetName(const PropagationBaseObject* object) {
2432  const std::string* name = gtl::FindOrNull(propagation_object_names_, object);
2433  if (name != nullptr) {
2434  return *name;
2435  }
2436  const IntegerCastInfo* const cast_info =
2437  gtl::FindOrNull(cast_information_, object);
2438  if (cast_info != nullptr && cast_info->expression != nullptr) {
2439  if (cast_info->expression->HasName()) {
2440  return absl::StrFormat("Var<%s>", cast_info->expression->name());
2441  } else if (parameters_.name_cast_variables()) {
2442  return absl::StrFormat("Var<%s>", cast_info->expression->DebugString());
2443  } else {
2444  const std::string new_name =
2445  absl::StrFormat("CastVar<%d>", anonymous_variable_index_++);
2446  propagation_object_names_[object] = new_name;
2447  return new_name;
2448  }
2449  }
2450  const std::string base_name = object->BaseName();
2451  if (parameters_.name_all_variables() && !base_name.empty()) {
2452  const std::string new_name =
2453  absl::StrFormat("%s_%d", base_name, anonymous_variable_index_++);
2454  propagation_object_names_[object] = new_name;
2455  return new_name;
2456  }
2457  return empty_name_;
2458 }
2459 
2460 void Solver::SetName(const PropagationBaseObject* object,
2461  const std::string& name) {
2462  if (parameters_.store_names() &&
2463  GetName(object) != name) { // in particular if name.empty()
2464  propagation_object_names_[object] = name;
2465  }
2466 }
2467 
2468 bool Solver::HasName(const PropagationBaseObject* const object) const {
2469  return gtl::ContainsKey(propagation_object_names_,
2470  const_cast<PropagationBaseObject*>(object)) ||
2471  (!object->BaseName().empty() && parameters_.name_all_variables());
2472 }
2473 
2474 // ------------------ Useful Operators ------------------
2475 
2476 std::ostream& operator<<(std::ostream& out, const Solver* const s) {
2477  out << s->DebugString();
2478  return out;
2479 }
2480 
2481 std::ostream& operator<<(std::ostream& out, const BaseObject* const o) {
2482  out << o->DebugString();
2483  return out;
2484 }
2485 
2486 // ---------- PropagationBaseObject ---------
2487 
2488 std::string PropagationBaseObject::name() const {
2489  return solver_->GetName(this);
2490 }
2491 
2492 void PropagationBaseObject::set_name(const std::string& name) {
2493  solver_->SetName(this, name);
2494 }
2495 
2496 bool PropagationBaseObject::HasName() const { return solver_->HasName(this); }
2497 
2498 std::string PropagationBaseObject::BaseName() const { return ""; }
2499 
2500 void PropagationBaseObject::ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
2501  solver_->ExecuteAll(demons);
2502 }
2503 
2504 void PropagationBaseObject::EnqueueAll(const SimpleRevFIFO<Demon*>& demons) {
2505  solver_->EnqueueAll(demons);
2506 }
2507 
2508 // ---------- Decision Builder ----------
2509 
2510 std::string DecisionBuilder::DebugString() const { return "DecisionBuilder"; }
2511 
2512 void DecisionBuilder::AppendMonitors(
2513  Solver* const solver, std::vector<SearchMonitor*>* const extras) {}
2514 
2515 void DecisionBuilder::Accept(ModelVisitor* const visitor) const {}
2516 
2517 // ---------- Decision and DecisionVisitor ----------
2518 
2519 void Decision::Accept(DecisionVisitor* const visitor) const {
2520  visitor->VisitUnknownDecision();
2521 }
2522 
2523 void DecisionVisitor::VisitSetVariableValue(IntVar* const var, int64 value) {}
2524 void DecisionVisitor::VisitSplitVariableDomain(IntVar* const var, int64 value,
2525  bool lower) {}
2526 void DecisionVisitor::VisitUnknownDecision() {}
2527 void DecisionVisitor::VisitScheduleOrPostpone(IntervalVar* const var,
2528  int64 est) {}
2529 void DecisionVisitor::VisitScheduleOrExpedite(IntervalVar* const var,
2530  int64 est) {}
2531 void DecisionVisitor::VisitRankFirstInterval(SequenceVar* const sequence,
2532  int index) {}
2533 
2534 void DecisionVisitor::VisitRankLastInterval(SequenceVar* const sequence,
2535  int index) {}
2536 
2537 // ---------- ModelVisitor ----------
2538 
2539 // Tags for constraints, arguments, extensions.
2540 
2541 const char ModelVisitor::kAbs[] = "Abs";
2542 const char ModelVisitor::kAbsEqual[] = "AbsEqual";
2543 const char ModelVisitor::kAllDifferent[] = "AllDifferent";
2544 const char ModelVisitor::kAllowedAssignments[] = "AllowedAssignments";
2545 const char ModelVisitor::kAtMost[] = "AtMost";
2546 const char ModelVisitor::kBetween[] = "Between";
2547 const char ModelVisitor::kConditionalExpr[] = "ConditionalExpr";
2548 const char ModelVisitor::kCircuit[] = "Circuit";
2549 const char ModelVisitor::kConvexPiecewise[] = "ConvexPiecewise";
2550 const char ModelVisitor::kCountEqual[] = "CountEqual";
2551 const char ModelVisitor::kCover[] = "Cover";
2552 const char ModelVisitor::kCumulative[] = "Cumulative";
2553 const char ModelVisitor::kDeviation[] = "Deviation";
2554 const char ModelVisitor::kDifference[] = "Difference";
2555 const char ModelVisitor::kDisjunctive[] = "Disjunctive";
2556 const char ModelVisitor::kDistribute[] = "Distribute";
2557 const char ModelVisitor::kDivide[] = "Divide";
2558 const char ModelVisitor::kDurationExpr[] = "DurationExpression";
2559 const char ModelVisitor::kElement[] = "Element";
2560 const char ModelVisitor::kElementEqual[] = "ElementEqual";
2561 const char ModelVisitor::kEndExpr[] = "EndExpression";
2562 const char ModelVisitor::kEquality[] = "Equal";
2563 const char ModelVisitor::kFalseConstraint[] = "FalseConstraint";
2564 const char ModelVisitor::kGlobalCardinality[] = "GlobalCardinality";
2565 const char ModelVisitor::kGreater[] = "Greater";
2566 const char ModelVisitor::kGreaterOrEqual[] = "GreaterOrEqual";
2567 const char ModelVisitor::kIndexOf[] = "IndexOf";
2568 const char ModelVisitor::kIntegerVariable[] = "IntegerVariable";
2569 const char ModelVisitor::kIntervalBinaryRelation[] = "IntervalBinaryRelation";
2570 const char ModelVisitor::kIntervalDisjunction[] = "IntervalDisjunction";
2571 const char ModelVisitor::kIntervalUnaryRelation[] = "IntervalUnaryRelation";
2572 const char ModelVisitor::kIntervalVariable[] = "IntervalVariable";
2573 const char ModelVisitor::kInversePermutation[] = "InversePermutation";
2574 const char ModelVisitor::kIsBetween[] = "IsBetween;";
2575 const char ModelVisitor::kIsDifferent[] = "IsDifferent";
2576 const char ModelVisitor::kIsEqual[] = "IsEqual";
2577 const char ModelVisitor::kIsGreater[] = "IsGreater";
2578 const char ModelVisitor::kIsGreaterOrEqual[] = "IsGreaterOrEqual";
2579 const char ModelVisitor::kIsLess[] = "IsLess";
2580 const char ModelVisitor::kIsLessOrEqual[] = "IsLessOrEqual";
2581 const char ModelVisitor::kIsMember[] = "IsMember;";
2582 const char ModelVisitor::kLess[] = "Less";
2583 const char ModelVisitor::kLessOrEqual[] = "LessOrEqual";
2584 const char ModelVisitor::kLexLess[] = "LexLess";
2585 const char ModelVisitor::kLinkExprVar[] = "CastExpressionIntoVariable";
2586 const char ModelVisitor::kMapDomain[] = "MapDomain";
2587 const char ModelVisitor::kMax[] = "Max";
2588 const char ModelVisitor::kMaxEqual[] = "MaxEqual";
2589 const char ModelVisitor::kMember[] = "Member";
2590 const char ModelVisitor::kMin[] = "Min";
2591 const char ModelVisitor::kMinEqual[] = "MinEqual";
2592 const char ModelVisitor::kModulo[] = "Modulo";
2593 const char ModelVisitor::kNoCycle[] = "NoCycle";
2594 const char ModelVisitor::kNonEqual[] = "NonEqual";
2595 const char ModelVisitor::kNotBetween[] = "NotBetween";
2596 const char ModelVisitor::kNotMember[] = "NotMember";
2597 const char ModelVisitor::kNullIntersect[] = "NullIntersect";
2598 const char ModelVisitor::kOpposite[] = "Opposite";
2599 const char ModelVisitor::kPack[] = "Pack";
2600 const char ModelVisitor::kPathCumul[] = "PathCumul";
2601 const char ModelVisitor::kDelayedPathCumul[] = "DelayedPathCumul";
2602 const char ModelVisitor::kPerformedExpr[] = "PerformedExpression";
2603 const char ModelVisitor::kPower[] = "Power";
2604 const char ModelVisitor::kProduct[] = "Product";
2605 const char ModelVisitor::kScalProd[] = "ScalarProduct";
2606 const char ModelVisitor::kScalProdEqual[] = "ScalarProductEqual";
2607 const char ModelVisitor::kScalProdGreaterOrEqual[] =
2608  "ScalarProductGreaterOrEqual";
2609 const char ModelVisitor::kScalProdLessOrEqual[] = "ScalarProductLessOrEqual";
2610 const char ModelVisitor::kSemiContinuous[] = "SemiContinuous";
2611 const char ModelVisitor::kSequenceVariable[] = "SequenceVariable";
2612 const char ModelVisitor::kSortingConstraint[] = "SortingConstraint";
2613 const char ModelVisitor::kSquare[] = "Square";
2614 const char ModelVisitor::kStartExpr[] = "StartExpression";
2615 const char ModelVisitor::kSum[] = "Sum";
2616 const char ModelVisitor::kSumEqual[] = "SumEqual";
2617 const char ModelVisitor::kSumGreaterOrEqual[] = "SumGreaterOrEqual";
2618 const char ModelVisitor::kSumLessOrEqual[] = "SumLessOrEqual";
2619 const char ModelVisitor::kTransition[] = "Transition";
2620 const char ModelVisitor::kTrace[] = "Trace";
2621 const char ModelVisitor::kTrueConstraint[] = "TrueConstraint";
2622 const char ModelVisitor::kVarBoundWatcher[] = "VarBoundWatcher";
2623 const char ModelVisitor::kVarValueWatcher[] = "VarValueWatcher";
2624 
2625 const char ModelVisitor::kCountAssignedItemsExtension[] = "CountAssignedItems";
2626 const char ModelVisitor::kCountUsedBinsExtension[] = "CountUsedBins";
2627 const char ModelVisitor::kInt64ToBoolExtension[] = "Int64ToBoolFunction";
2628 const char ModelVisitor::kInt64ToInt64Extension[] = "Int64ToInt64Function";
2629 const char ModelVisitor::kObjectiveExtension[] = "Objective";
2630 const char ModelVisitor::kSearchLimitExtension[] = "SearchLimit";
2631 const char ModelVisitor::kUsageEqualVariableExtension[] = "UsageEqualVariable";
2632 
2633 const char ModelVisitor::kUsageLessConstantExtension[] = "UsageLessConstant";
2634 const char ModelVisitor::kVariableGroupExtension[] = "VariableGroup";
2635 const char ModelVisitor::kVariableUsageLessConstantExtension[] =
2636  "VariableUsageLessConstant";
2637 const char ModelVisitor::kWeightedSumOfAssignedEqualVariableExtension[] =
2638  "WeightedSumOfAssignedEqualVariable";
2639 
2640 const char ModelVisitor::kActiveArgument[] = "active";
2641 const char ModelVisitor::kAssumePathsArgument[] = "assume_paths";
2642 const char ModelVisitor::kBranchesLimitArgument[] = "branches_limit";
2643 const char ModelVisitor::kCapacityArgument[] = "capacity";
2644 const char ModelVisitor::kCardsArgument[] = "cardinalities";
2645 const char ModelVisitor::kCoefficientsArgument[] = "coefficients";
2646 const char ModelVisitor::kCountArgument[] = "count";
2647 const char ModelVisitor::kCumulativeArgument[] = "cumulative";
2648 const char ModelVisitor::kCumulsArgument[] = "cumuls";
2649 const char ModelVisitor::kDemandsArgument[] = "demands";
2650 const char ModelVisitor::kDurationMinArgument[] = "duration_min";
2651 const char ModelVisitor::kDurationMaxArgument[] = "duration_max";
2652 const char ModelVisitor::kEarlyCostArgument[] = "early_cost";
2653 const char ModelVisitor::kEarlyDateArgument[] = "early_date";
2654 const char ModelVisitor::kEndMinArgument[] = "end_min";
2655 const char ModelVisitor::kEndMaxArgument[] = "end_max";
2656 const char ModelVisitor::kEndsArgument[] = "ends";
2657 const char ModelVisitor::kExpressionArgument[] = "expression";
2658 const char ModelVisitor::kFailuresLimitArgument[] = "failures_limit";
2659 const char ModelVisitor::kFinalStatesArgument[] = "final_states";
2660 const char ModelVisitor::kFixedChargeArgument[] = "fixed_charge";
2661 const char ModelVisitor::kIndex2Argument[] = "index2";
2662 const char ModelVisitor::kIndexArgument[] = "index";
2663 const char ModelVisitor::kInitialState[] = "initial_state";
2664 const char ModelVisitor::kIntervalArgument[] = "interval";
2665 const char ModelVisitor::kIntervalsArgument[] = "intervals";
2666 const char ModelVisitor::kLateCostArgument[] = "late_cost";
2667 const char ModelVisitor::kLateDateArgument[] = "late_date";
2668 const char ModelVisitor::kLeftArgument[] = "left";
2669 const char ModelVisitor::kMaxArgument[] = "max_value";
2670 const char ModelVisitor::kMaximizeArgument[] = "maximize";
2671 const char ModelVisitor::kMinArgument[] = "min_value";
2672 const char ModelVisitor::kModuloArgument[] = "modulo";
2673 const char ModelVisitor::kNextsArgument[] = "nexts";
2674 const char ModelVisitor::kOptionalArgument[] = "optional";
2675 const char ModelVisitor::kPartialArgument[] = "partial";
2676 const char ModelVisitor::kPositionXArgument[] = "position_x";
2677 const char ModelVisitor::kPositionYArgument[] = "position_y";
2678 const char ModelVisitor::kRangeArgument[] = "range";
2679 const char ModelVisitor::kRelationArgument[] = "relation";
2680 const char ModelVisitor::kRightArgument[] = "right";
2681 const char ModelVisitor::kSequenceArgument[] = "sequence";
2682 const char ModelVisitor::kSequencesArgument[] = "sequences";
2683 const char ModelVisitor::kSmartTimeCheckArgument[] = "smart_time_check";
2684 const char ModelVisitor::kSizeArgument[] = "size";
2685 const char ModelVisitor::kSizeXArgument[] = "size_x";
2686 const char ModelVisitor::kSizeYArgument[] = "size_y";
2687 const char ModelVisitor::kSolutionLimitArgument[] = "solutions_limit";
2688 const char ModelVisitor::kStartMinArgument[] = "start_min";
2689 const char ModelVisitor::kStartMaxArgument[] = "start_max";
2690 const char ModelVisitor::kStartsArgument[] = "starts";
2691 const char ModelVisitor::kStepArgument[] = "step";
2692 const char ModelVisitor::kTargetArgument[] = "target_variable";
2693 const char ModelVisitor::kTimeLimitArgument[] = "time_limit";
2694 const char ModelVisitor::kTransitsArgument[] = "transits";
2695 const char ModelVisitor::kTuplesArgument[] = "tuples";
2696 const char ModelVisitor::kValueArgument[] = "value";
2697 const char ModelVisitor::kValuesArgument[] = "values";
2698 const char ModelVisitor::kVarsArgument[] = "variables";
2699 const char ModelVisitor::kEvaluatorArgument[] = "evaluator";
2700 
2701 const char ModelVisitor::kVariableArgument[] = "variable";
2702 
2703 const char ModelVisitor::kMirrorOperation[] = "mirror";
2704 const char ModelVisitor::kRelaxedMaxOperation[] = "relaxed_max";
2705 const char ModelVisitor::kRelaxedMinOperation[] = "relaxed_min";
2706 const char ModelVisitor::kSumOperation[] = "sum";
2707 const char ModelVisitor::kDifferenceOperation[] = "difference";
2708 const char ModelVisitor::kProductOperation[] = "product";
2709 const char ModelVisitor::kStartSyncOnStartOperation[] = "start_synced_on_start";
2710 const char ModelVisitor::kStartSyncOnEndOperation[] = "start_synced_on_end";
2711 const char ModelVisitor::kTraceOperation[] = "trace";
2712 
2713 // Methods
2714 
2715 ModelVisitor::~ModelVisitor() {}
2716 
2717 void ModelVisitor::BeginVisitModel(const std::string& type_name) {}
2718 void ModelVisitor::EndVisitModel(const std::string& type_name) {}
2719 
2720 void ModelVisitor::BeginVisitConstraint(const std::string& type_name,
2721  const Constraint* const constraint) {}
2722 void ModelVisitor::EndVisitConstraint(const std::string& type_name,
2723  const Constraint* const constraint) {}
2724 
2725 void ModelVisitor::BeginVisitExtension(const std::string& type) {}
2726 void ModelVisitor::EndVisitExtension(const std::string& type) {}
2727 
2728 void ModelVisitor::BeginVisitIntegerExpression(const std::string& type_name,
2729  const IntExpr* const expr) {}
2730 void ModelVisitor::EndVisitIntegerExpression(const std::string& type_name,
2731  const IntExpr* const expr) {}
2732 
2733 void ModelVisitor::VisitIntegerVariable(const IntVar* const variable,
2734  IntExpr* const delegate) {
2735  if (delegate != nullptr) {
2736  delegate->Accept(this);
2737  }
2738 }
2739 
2740 void ModelVisitor::VisitIntegerVariable(const IntVar* const variable,
2741  const std::string& operation,
2742  int64 value, IntVar* const delegate) {
2743  if (delegate != nullptr) {
2744  delegate->Accept(this);
2745  }
2746 }
2747 
2748 void ModelVisitor::VisitIntervalVariable(const IntervalVar* const variable,
2749  const std::string& operation,
2750  int64 value,
2751  IntervalVar* const delegate) {
2752  if (delegate != nullptr) {
2753  delegate->Accept(this);
2754  }
2755 }
2756 
2757 void ModelVisitor::VisitSequenceVariable(const SequenceVar* const variable) {
2758  for (int i = 0; i < variable->size(); ++i) {
2759  variable->Interval(i)->Accept(this);
2760  }
2761 }
2762 
2763 void ModelVisitor::VisitIntegerArgument(const std::string& arg_name,
2764  int64 value) {}
2765 
2766 void ModelVisitor::VisitIntegerArrayArgument(const std::string& arg_name,
2767  const std::vector<int64>& values) {
2768 }
2769 
2770 void ModelVisitor::VisitIntegerMatrixArgument(const std::string& arg_name,
2771  const IntTupleSet& tuples) {}
2772 
2773 void ModelVisitor::VisitIntegerExpressionArgument(const std::string& arg_name,
2774  IntExpr* const argument) {
2775  argument->Accept(this);
2776 }
2777 
2778 void ModelVisitor::VisitIntegerVariableEvaluatorArgument(
2779  const std::string& arg_name, const Solver::Int64ToIntVar& arguments) {}
2780 
2781 void ModelVisitor::VisitIntegerVariableArrayArgument(
2782  const std::string& arg_name, const std::vector<IntVar*>& arguments) {
2783  ForAll(arguments, &IntVar::Accept, this);
2784 }
2785 
2786 void ModelVisitor::VisitIntervalArgument(const std::string& arg_name,
2787  IntervalVar* const argument) {
2788  argument->Accept(this);
2789 }
2790 
2791 void ModelVisitor::VisitIntervalArrayArgument(
2792  const std::string& arg_name, const std::vector<IntervalVar*>& arguments) {
2793  ForAll(arguments, &IntervalVar::Accept, this);
2794 }
2795 
2796 void ModelVisitor::VisitSequenceArgument(const std::string& arg_name,
2797  SequenceVar* const argument) {
2798  argument->Accept(this);
2799 }
2800 
2801 void ModelVisitor::VisitSequenceArrayArgument(
2802  const std::string& arg_name, const std::vector<SequenceVar*>& arguments) {
2803  ForAll(arguments, &SequenceVar::Accept, this);
2804 }
2805 
2806 // ----- Helpers -----
2807 
2808 void ModelVisitor::VisitInt64ToBoolExtension(Solver::IndexFilter1 filter,
2809  int64 index_min, int64 index_max) {
2810  if (filter != nullptr) {
2811  std::vector<int64> cached_results;
2812  for (int i = index_min; i <= index_max; ++i) {
2813  cached_results.push_back(filter(i));
2814  }
2815  BeginVisitExtension(kInt64ToBoolExtension);
2816  VisitIntegerArgument(kMinArgument, index_min);
2817  VisitIntegerArgument(kMaxArgument, index_max);
2818  VisitIntegerArrayArgument(kValuesArgument, cached_results);
2819  EndVisitExtension(kInt64ToBoolExtension);
2820  }
2821 }
2822 
2823 void ModelVisitor::VisitInt64ToInt64Extension(
2824  const Solver::IndexEvaluator1& eval, int64 index_min, int64 index_max) {
2825  CHECK(eval != nullptr);
2826  std::vector<int64> cached_results;
2827  for (int i = index_min; i <= index_max; ++i) {
2828  cached_results.push_back(eval(i));
2829  }
2830  BeginVisitExtension(kInt64ToInt64Extension);
2831  VisitIntegerArgument(kMinArgument, index_min);
2832  VisitIntegerArgument(kMaxArgument, index_max);
2833  VisitIntegerArrayArgument(kValuesArgument, cached_results);
2834  EndVisitExtension(kInt64ToInt64Extension);
2835 }
2836 
2837 void ModelVisitor::VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1& eval,
2838  const std::string& arg_name,
2839  int64 index_max) {
2840  CHECK(eval != nullptr);
2841  std::vector<int64> cached_results;
2842  for (int i = 0; i <= index_max; ++i) {
2843  cached_results.push_back(eval(i));
2844  }
2845  VisitIntegerArrayArgument(arg_name, cached_results);
2846 }
2847 
2848 // ---------- Search Monitor ----------
2849 
2850 void SearchMonitor::EnterSearch() {}
2851 void SearchMonitor::RestartSearch() {}
2852 void SearchMonitor::ExitSearch() {}
2853 void SearchMonitor::BeginNextDecision(DecisionBuilder* const b) {}
2854 void SearchMonitor::EndNextDecision(DecisionBuilder* const b,
2855  Decision* const d) {}
2856 void SearchMonitor::ApplyDecision(Decision* const d) {}
2857 void SearchMonitor::RefuteDecision(Decision* const d) {}
2858 void SearchMonitor::AfterDecision(Decision* const d, bool apply) {}
2859 void SearchMonitor::BeginFail() {}
2860 void SearchMonitor::EndFail() {}
2861 void SearchMonitor::BeginInitialPropagation() {}
2862 void SearchMonitor::EndInitialPropagation() {}
2863 bool SearchMonitor::AcceptSolution() { return true; }
2864 bool SearchMonitor::AtSolution() { return false; }
2865 void SearchMonitor::NoMoreSolutions() {}
2866 bool SearchMonitor::LocalOptimum() { return false; }
2867 bool SearchMonitor::AcceptDelta(Assignment* delta, Assignment* deltadelta) {
2868  return true;
2869 }
2872 void SearchMonitor::PeriodicCheck() {}
2873 void SearchMonitor::Accept(ModelVisitor* const visitor) const {}
2874 // A search monitors adds itself on the active search.
2875 void SearchMonitor::Install() {
2876  solver()->searches_.back()->push_monitor(this);
2877 }
2878 
2879 // ---------- Propagation Monitor -----------
2880 PropagationMonitor::PropagationMonitor(Solver* const solver)
2881  : SearchMonitor(solver) {}
2882 
2884 
2885 // A propagation monitor listens to search events as well as propagation events.
2887  SearchMonitor::Install();
2888  solver()->AddPropagationMonitor(this);
2889 }
2890 
2891 // ---------- Local Search Monitor -----------
2893  : SearchMonitor(solver) {}
2894 
2896 
2897 // A local search monitor listens to search events as well as local search
2898 // events.
2900  SearchMonitor::Install();
2901  solver()->AddLocalSearchMonitor(this);
2902 }
2903 
2904 // ---------- Trace ----------
2905 
2906 class Trace : public PropagationMonitor {
2907  public:
2908  explicit Trace(Solver* const s) : PropagationMonitor(s) {}
2909 
2910  ~Trace() override {}
2911 
2913  Constraint* const constraint) override {
2915  constraint);
2916  }
2917 
2918  void EndConstraintInitialPropagation(Constraint* const constraint) override {
2920  constraint);
2921  }
2922 
2924  Constraint* const parent, Constraint* const nested) override {
2925  ForAll(monitors_,
2927  nested);
2928  }
2929 
2931  Constraint* const parent, Constraint* const nested) override {
2932  ForAll(monitors_,
2934  nested);
2935  }
2936 
2937  void RegisterDemon(Demon* const demon) override {
2938  ForAll(monitors_, &PropagationMonitor::RegisterDemon, demon);
2939  }
2940 
2941  void BeginDemonRun(Demon* const demon) override {
2942  ForAll(monitors_, &PropagationMonitor::BeginDemonRun, demon);
2943  }
2944 
2945  void EndDemonRun(Demon* const demon) override {
2946  ForAll(monitors_, &PropagationMonitor::EndDemonRun, demon);
2947  }
2948 
2949  void StartProcessingIntegerVariable(IntVar* const var) override {
2951  }
2952 
2953  void EndProcessingIntegerVariable(IntVar* const var) override {
2955  }
2956 
2957  void PushContext(const std::string& context) override {
2958  ForAll(monitors_, &PropagationMonitor::PushContext, context);
2959  }
2960 
2961  void PopContext() override {
2962  ForAll(monitors_, &PropagationMonitor::PopContext);
2963  }
2964 
2965  // IntExpr modifiers.
2966  void SetMin(IntExpr* const expr, int64 new_min) override {
2967  for (PropagationMonitor* const monitor : monitors_) {
2968  monitor->SetMin(expr, new_min);
2969  }
2970  }
2971 
2972  void SetMax(IntExpr* const expr, int64 new_max) override {
2973  for (PropagationMonitor* const monitor : monitors_) {
2974  monitor->SetMax(expr, new_max);
2975  }
2976  }
2977 
2978  void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) override {
2979  for (PropagationMonitor* const monitor : monitors_) {
2980  monitor->SetRange(expr, new_min, new_max);
2981  }
2982  }
2983 
2984  // IntVar modifiers.
2985  void SetMin(IntVar* const var, int64 new_min) override {
2986  for (PropagationMonitor* const monitor : monitors_) {
2987  monitor->SetMin(var, new_min);
2988  }
2989  }
2990 
2991  void SetMax(IntVar* const var, int64 new_max) override {
2992  for (PropagationMonitor* const monitor : monitors_) {
2993  monitor->SetMax(var, new_max);
2994  }
2995  }
2996 
2997  void SetRange(IntVar* const var, int64 new_min, int64 new_max) override {
2998  for (PropagationMonitor* const monitor : monitors_) {
2999  monitor->SetRange(var, new_min, new_max);
3000  }
3001  }
3002 
3003  void RemoveValue(IntVar* const var, int64 value) override {
3004  ForAll(monitors_, &PropagationMonitor::RemoveValue, var, value);
3005  }
3006 
3007  void SetValue(IntVar* const var, int64 value) override {
3008  ForAll(monitors_, &PropagationMonitor::SetValue, var, value);
3009  }
3010 
3011  void RemoveInterval(IntVar* const var, int64 imin, int64 imax) override {
3012  ForAll(monitors_, &PropagationMonitor::RemoveInterval, var, imin, imax);
3013  }
3014 
3015  void SetValues(IntVar* const var, const std::vector<int64>& values) override {
3016  ForAll(monitors_, &PropagationMonitor::SetValues, var, values);
3017  }
3018 
3019  void RemoveValues(IntVar* const var,
3020  const std::vector<int64>& values) override {
3021  ForAll(monitors_, &PropagationMonitor::RemoveValues, var, values);
3022  }
3023 
3024  // IntervalVar modifiers.
3025  void SetStartMin(IntervalVar* const var, int64 new_min) override {
3026  ForAll(monitors_, &PropagationMonitor::SetStartMin, var, new_min);
3027  }
3028 
3029  void SetStartMax(IntervalVar* const var, int64 new_max) override {
3030  ForAll(monitors_, &PropagationMonitor::SetStartMax, var, new_max);
3031  }
3032 
3033  void SetStartRange(IntervalVar* const var, int64 new_min,
3034  int64 new_max) override {
3035  ForAll(monitors_, &PropagationMonitor::SetStartRange, var, new_min,
3036  new_max);
3037  }
3038 
3039  void SetEndMin(IntervalVar* const var, int64 new_min) override {
3040  ForAll(monitors_, &PropagationMonitor::SetEndMin, var, new_min);
3041  }
3042 
3043  void SetEndMax(IntervalVar* const var, int64 new_max) override {
3044  ForAll(monitors_, &PropagationMonitor::SetEndMax, var, new_max);
3045  }
3046 
3047  void SetEndRange(IntervalVar* const var, int64 new_min,
3048  int64 new_max) override {
3049  ForAll(monitors_, &PropagationMonitor::SetEndRange, var, new_min, new_max);
3050  }
3051 
3052  void SetDurationMin(IntervalVar* const var, int64 new_min) override {
3053  ForAll(monitors_, &PropagationMonitor::SetDurationMin, var, new_min);
3054  }
3055 
3056  void SetDurationMax(IntervalVar* const var, int64 new_max) override {
3057  ForAll(monitors_, &PropagationMonitor::SetDurationMax, var, new_max);
3058  }
3059 
3060  void SetDurationRange(IntervalVar* const var, int64 new_min,
3061  int64 new_max) override {
3062  ForAll(monitors_, &PropagationMonitor::SetDurationRange, var, new_min,
3063  new_max);
3064  }
3065 
3066  void SetPerformed(IntervalVar* const var, bool value) override {
3067  ForAll(monitors_, &PropagationMonitor::SetPerformed, var, value);
3068  }
3069 
3070  void RankFirst(SequenceVar* const var, int index) override {
3071  ForAll(monitors_, &PropagationMonitor::RankFirst, var, index);
3072  }
3073 
3074  void RankNotFirst(SequenceVar* const var, int index) override {
3075  ForAll(monitors_, &PropagationMonitor::RankNotFirst, var, index);
3076  }
3077 
3078  void RankLast(SequenceVar* const var, int index) override {
3079  ForAll(monitors_, &PropagationMonitor::RankLast, var, index);
3080  }
3081 
3082  void RankNotLast(SequenceVar* const var, int index) override {
3083  ForAll(monitors_, &PropagationMonitor::RankNotLast, var, index);
3084  }
3085 
3086  void RankSequence(SequenceVar* const var, const std::vector<int>& rank_first,
3087  const std::vector<int>& rank_last,
3088  const std::vector<int>& unperformed) override {
3089  ForAll(monitors_, &PropagationMonitor::RankSequence, var, rank_first,
3090  rank_last, unperformed);
3091  }
3092 
3093  // Does not take ownership of monitor.
3094  void Add(PropagationMonitor* const monitor) {
3095  if (monitor != nullptr) {
3096  monitors_.push_back(monitor);
3097  }
3098  }
3099 
3100  // The trace will dispatch propagation events. It needs to listen to search
3101  // events.
3102  void Install() override { SearchMonitor::Install(); }
3103 
3104  std::string DebugString() const override { return "Trace"; }
3105 
3106  private:
3107  std::vector<PropagationMonitor*> monitors_;
3108 };
3109 
3110 PropagationMonitor* BuildTrace(Solver* const s) { return new Trace(s); }
3111 
3112 void Solver::AddPropagationMonitor(PropagationMonitor* const monitor) {
3113  // TODO(user): Check solver state?
3114  reinterpret_cast<class Trace*>(propagation_monitor_.get())->Add(monitor);
3115 }
3116 
3117 PropagationMonitor* Solver::GetPropagationMonitor() const {
3118  return propagation_monitor_.get();
3119 }
3120 
3121 // ---------- Local Search Monitor Master ----------
3122 
3124  public:
3125  explicit LocalSearchMonitorMaster(Solver* solver)
3126  : LocalSearchMonitor(solver) {}
3127 
3128  void BeginOperatorStart() override {
3129  ForAll(monitors_, &LocalSearchMonitor::BeginOperatorStart);
3130  }
3131  void EndOperatorStart() override {
3132  ForAll(monitors_, &LocalSearchMonitor::EndOperatorStart);
3133  }
3134  void BeginMakeNextNeighbor(const LocalSearchOperator* op) override {
3135  ForAll(monitors_, &LocalSearchMonitor::BeginMakeNextNeighbor, op);
3136  }
3137  void EndMakeNextNeighbor(const LocalSearchOperator* op, bool neighbor_found,
3138  const Assignment* delta,
3139  const Assignment* deltadelta) override {
3140  ForAll(monitors_, &LocalSearchMonitor::EndMakeNextNeighbor, op,
3141  neighbor_found, delta, deltadelta);
3142  }
3143  void BeginFilterNeighbor(const LocalSearchOperator* op) override {
3144  ForAll(monitors_, &LocalSearchMonitor::BeginFilterNeighbor, op);
3145  }
3147  bool neighbor_found) override {
3148  ForAll(monitors_, &LocalSearchMonitor::EndFilterNeighbor, op,
3149  neighbor_found);
3150  }
3151  void BeginAcceptNeighbor(const LocalSearchOperator* op) override {
3152  ForAll(monitors_, &LocalSearchMonitor::BeginAcceptNeighbor, op);
3153  }
3155  bool neighbor_found) override {
3156  ForAll(monitors_, &LocalSearchMonitor::EndAcceptNeighbor, op,
3157  neighbor_found);
3158  }
3159  void BeginFiltering(const LocalSearchFilter* filter) override {
3160  ForAll(monitors_, &LocalSearchMonitor::BeginFiltering, filter);
3161  }
3162  void EndFiltering(const LocalSearchFilter* filter, bool reject) override {
3163  ForAll(monitors_, &LocalSearchMonitor::EndFiltering, filter, reject);
3164  }
3165 
3166  // Does not take ownership of monitor.
3167  void Add(LocalSearchMonitor* monitor) {
3168  if (monitor != nullptr) {
3169  monitors_.push_back(monitor);
3170  }
3171  }
3172 
3173  // The trace will dispatch propagation events. It needs to listen to search
3174  // events.
3175  void Install() override { SearchMonitor::Install(); }
3176 
3177  std::string DebugString() const override {
3178  return "LocalSearchMonitorMaster";
3179  }
3180 
3181  private:
3182  std::vector<LocalSearchMonitor*> monitors_;
3183 };
3184 
3186  return new LocalSearchMonitorMaster(s);
3187 }
3188 
3189 void Solver::AddLocalSearchMonitor(LocalSearchMonitor* const monitor) {
3190  reinterpret_cast<class LocalSearchMonitorMaster*>(local_search_monitor_.get())
3191  ->Add(monitor);
3192 }
3193 
3194 LocalSearchMonitor* Solver::GetLocalSearchMonitor() const {
3195  return local_search_monitor_.get();
3196 }
3197 
3198 void Solver::SetSearchContext(Search* search,
3199  const std::string& search_context) {
3200  search->set_search_context(search_context);
3201 }
3202 
3203 std::string Solver::SearchContext() const {
3204  return ActiveSearch()->search_context();
3205 }
3206 
3207 std::string Solver::SearchContext(const Search* search) const {
3208  return search->search_context();
3209 }
3210 
3211 Assignment* Solver::GetOrCreateLocalSearchState() {
3212  if (local_search_state_ == nullptr) {
3213  local_search_state_ = absl::make_unique<Assignment>(this);
3214  }
3215  return local_search_state_.get();
3216 }
3217 
3218 // ----------------- Constraint class -------------------
3219 
3220 std::string Constraint::DebugString() const { return "Constraint"; }
3221 
3222 void Constraint::PostAndPropagate() {
3223  FreezeQueue();
3224  Post();
3225  InitialPropagate();
3226  solver()->CheckFail();
3227  UnfreezeQueue();
3228 }
3229 
3230 void Constraint::Accept(ModelVisitor* const visitor) const {
3231  visitor->BeginVisitConstraint("unknown", this);
3232  VLOG(3) << "Unknown constraint " << DebugString();
3233  visitor->EndVisitConstraint("unknown", this);
3234 }
3235 
3236 bool Constraint::IsCastConstraint() const {
3237  return gtl::ContainsKey(solver()->cast_constraints_, this);
3238 }
3239 
3240 IntVar* Constraint::Var() { return nullptr; }
3241 
3242 // ----- Class IntExpr -----
3243 
3244 void IntExpr::Accept(ModelVisitor* const visitor) const {
3245  visitor->BeginVisitIntegerExpression("unknown", this);
3246  VLOG(3) << "Unknown expression " << DebugString();
3247  visitor->EndVisitIntegerExpression("unknown", this);
3248 }
3249 
3250 #undef CP_TRY // We no longer need those.
3251 #undef CP_ON_FAIL
3252 #undef CP_DO_FAIL
3253 
3254 } // namespace operations_research
operations_research::Trace::EndDemonRun
void EndDemonRun(Demon *const demon) override
Definition: constraint_solver.cc:2945
operations_research::Trace::SetStartRange
void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max) override
Definition: constraint_solver.cc:3033
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::InstallDemonProfiler
void InstallDemonProfiler(DemonProfiler *const monitor)
Definition: demon_profiler.cc:438
operations_research::PropagationMonitor::SetStartRange
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
operations_research::LocalSearchMonitor::EndFiltering
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
operations_research::LocalSearchMonitorMaster::EndFilterNeighbor
void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
Definition: constraint_solver.cc:3146
operations_research::PropagationMonitor::SetDurationRange
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
operations_research::Search::RefuteDecision
void RefuteDecision(Decision *const d)
Definition: constraint_solver.cc:1234
compressed
std::string compressed
Definition: constraint_solver.cc:666
operations_research::PropagationMonitor::RankFirst
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
operations_research::Search::IncrementSolutionCounter
void IncrementSolutionCounter()
Definition: constraint_solver.cc:1010
operations_research::Search::EndInitialPropagation
void EndInitialPropagation()
Definition: constraint_solver.cc:1247
operations_research::Search::BeginInitialPropagation
void BeginInitialPropagation()
Definition: constraint_solver.cc:1243
operations_research::Trace::SetDurationMax
void SetDurationMax(IntervalVar *const var, int64 new_max) override
Definition: constraint_solver.cc:3056
operations_research::Search
Definition: constraint_solver.cc:946
integral_types.h
map_util.h
operations_research::LocalSearchMonitor::EndFilterNeighbor
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
operations_research::PropagationMonitor::EndConstraintInitialPropagation
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
operations_research::LocalSearchMonitor::EndMakeNextNeighbor
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
operations_research::LocalSearchMonitorMaster::BeginAcceptNeighbor
void BeginAcceptNeighbor(const LocalSearchOperator *op) override
Definition: constraint_solver.cc:3151
operations_research::Search::solution_counter
int64 solution_counter() const
Definition: constraint_solver.cc:1011
operations_research::Queue::AfterFailure
void AfterFailure()
Definition: constraint_solver.cc:330
operations_research::Search::Search
Search(Solver *const s, int)
Definition: constraint_solver.cc:967
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::Search::AfterDecision
void AfterDecision(Decision *const d, bool apply)
Definition: constraint_solver.cc:1229
current_
int64 current_
Definition: search.cc:2947
operations_research::Search::search_depth
int search_depth() const
Definition: constraint_solver.cc:1035
operations_research::PropagationMonitor::EndNestedConstraintInitialPropagation
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
operations_research::Trace::RemoveValue
void RemoveValue(IntVar *const var, int64 value) override
Definition: constraint_solver.cc:3003
operations_research::Search::ExitSearch
void ExitSearch()
Definition: constraint_solver.cc:1205
operations_research::Trace::BeginNestedConstraintInitialPropagation
void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
Definition: constraint_solver.cc:2923
operations_research::PropagationMonitor::EndDemonRun
virtual void EndDemonRun(Demon *const demon)=0
operations_research::Queue::ExecuteAll
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
Definition: constraint_solver.cc:273
operations_research::Search::set_decision_builder
void set_decision_builder(DecisionBuilder *const db)
Definition: constraint_solver.cc:1016
operations_research::Trace::RankNotLast
void RankNotLast(SequenceVar *const var, int index) override
Definition: constraint_solver.cc:3082
recordio.h
operations_research::Trace::RankSequence
void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed) override
Definition: constraint_solver.cc:3086
operations_research::LocalSearchMonitor::BeginFilterNeighbor
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
operations_research::Trail::rev_uint64s_
CompressedTrail< uint64 > rev_uint64s_
Definition: constraint_solver.cc:719
operations_research::LocalSearchMonitorMaster::Add
void Add(LocalSearchMonitor *monitor)
Definition: constraint_solver.cc:3167
operations_research::PropagationMonitor::SetStartMin
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
operations_research::Search::Solver
friend class Solver
Definition: constraint_solver.cc:1052
operations_research::LocalSearchMonitorMaster::BeginFilterNeighbor
void BeginFilterNeighbor(const LocalSearchOperator *op) override
Definition: constraint_solver.cc:3143
operations_research::PropagationMonitor::SetDurationMin
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
operations_research::Trace::PopContext
void PopContext() override
Definition: constraint_solver.cc:2961
GG_ULONGLONG
#define GG_ULONGLONG(x)
Definition: integral_types.h:47
logging.h
operations_research::Trace::RankLast
void RankLast(SequenceVar *const var, int index) override
Definition: constraint_solver.cc:3078
operations_research::PropagationMonitor::BeginNestedConstraintInitialPropagation
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
operations_research::PropagationMonitor::BeginDemonRun
virtual void BeginDemonRun(Demon *const demon)=0
operations_research::Trace::DebugString
std::string DebugString() const override
Definition: constraint_solver.cc:3104
operations_research::Trace::SetDurationRange
void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max) override
Definition: constraint_solver.cc:3060
operations_research::LocalSearchMonitor::EndOperatorStart
virtual void EndOperatorStart()=0
stamp_
const int64 stamp_
Definition: search.cc:3033
operations_research::StateInfo::int_info
int int_info
Definition: constraint_solver.cc:437
operations_research::Search::set_should_finish
void set_should_finish(bool s)
Definition: constraint_solver.cc:1041
operations_research::Trace::SetRange
void SetRange(IntExpr *const expr, int64 new_min, int64 new_max) override
Definition: constraint_solver.cc:2978
operations_research::LocalSearchMonitorMaster::LocalSearchMonitorMaster
LocalSearchMonitorMaster(Solver *solver)
Definition: constraint_solver.cc:3125
operations_research::LocalSearchMonitor::~LocalSearchMonitor
~LocalSearchMonitor() override
Definition: constraint_solver.cc:2895
operations_research::Search::LeftMove
void LeftMove()
Definition: constraint_solver.cc:1024
operations_research::CleanVariableOnFail
void CleanVariableOnFail(IntVar *const var)
Definition: expressions.cc:6325
value
int64 value
Definition: demon_profiler.cc:43
operations_research::PropagationMonitor::~PropagationMonitor
~PropagationMonitor() override
Definition: constraint_solver.cc:2883
kuint64max
static const uint64 kuint64max
Definition: integral_types.h:52
operations_research::Trace::SetStartMin
void SetStartMin(IntervalVar *const var, int64 new_min) override
IntervalVar modifiers.
Definition: constraint_solver.cc:3025
operations_research::AcceptNeighbor
void AcceptNeighbor(Search *const search)
Definition: constraint_solver.cc:1346
operations_research::Trail::rev_ptrs_
CompressedTrail< void * > rev_ptrs_
Definition: constraint_solver.cc:721
operations_research::DeleteDemonProfiler
void DeleteDemonProfiler(DemonProfiler *const monitor)
Definition: demon_profiler.cc:448
operations_research::Trail
Definition: constraint_solver.cc:716
operations_research::Search::NoMoreSolutions
void NoMoreSolutions()
Definition: constraint_solver.cc:1277
macros.h
operations_research::BuildModelCache
ModelCache * BuildModelCache(Solver *const solver)
Definition: model_cache.cc:845
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::Queue::EnqueueDelayedDemon
void EnqueueDelayedDemon(Demon *const demon)
Definition: constraint_solver.cc:322
tuple_set.h
operations_research::Trace::PushContext
void PushContext(const std::string &context) override
Definition: constraint_solver.cc:2957
operations_research::InternalSaveBooleanVarValue
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
Definition: constraint_solver.cc:940
operations_research::Queue::ProcessConstraints
void ProcessConstraints()
Definition: constraint_solver.cc:374
operations_research::Queue::increase_stamp
void increase_stamp()
Definition: constraint_solver.cc:350
operations_research::PropagationMonitor::RegisterDemon
virtual void RegisterDemon(Demon *const demon)=0
CP_DO_FAIL
#define CP_DO_FAIL(search)
Definition: constraint_solver.cc:1099
operations_research::DeleteLocalSearchProfiler
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
Definition: local_search.cc:3569
operations_research::Queue::EnqueueAll
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
Definition: constraint_solver.cc:305
operations_research::StateMarker::Solver
friend class Solver
Definition: constraint_solver.cc:446
operations_research::Queue::set_action_on_fail
void set_action_on_fail(Solver::Action a)
Definition: constraint_solver.cc:354
operations_research::LocalSearchMonitorMaster::DebugString
std::string DebugString() const override
Definition: constraint_solver.cc:3177
int64
int64_t int64
Definition: integral_types.h:34
constraint_solveri.h
operations_research::Search::AtSolution
bool AtSolution()
Definition: constraint_solver.cc:1264
operations_research::Trace::StartProcessingIntegerVariable
void StartProcessingIntegerVariable(IntVar *const var) override
Definition: constraint_solver.cc:2949
operations_research::PropagationMonitor::BeginConstraintInitialPropagation
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
index
int index
Definition: pack.cc:508
operations_research::Search::EnterSearch
void EnterSearch()
Definition: constraint_solver.cc:1195
operations_research::Trail::rev_boolvar_list_
std::vector< IntVar * > rev_boolvar_list_
Definition: constraint_solver.cc:722
context
GurobiMPCallbackContext * context
Definition: gurobi_interface.cc:439
operations_research::StateInfo::StateInfo
StateInfo(Solver::Action a, bool fast)
Definition: constraint_solver.cc:429
DEFINE_string
DEFINE_string(cp_profile_file, "", "Export profiling overview to file.")
operations_research::Search::ApplyDecision
void ApplyDecision(Decision *const d)
Definition: constraint_solver.cc:1224
operations_research::StateInfo::reversible_action
Solver::Action reversible_action
Definition: constraint_solver.cc:440
operations_research::Trace::EndConstraintInitialPropagation
void EndConstraintInitialPropagation(Constraint *const constraint) override
Definition: constraint_solver.cc:2918
operations_research::Trace::SetPerformed
void SetPerformed(IntervalVar *const var, bool value) override
Definition: constraint_solver.cc:3066
operations_research::PropagationMonitor::SetValue
virtual void SetValue(IntVar *const var, int64 value)=0
operations_research::Search::ModifyDecision
Solver::DecisionModification ModifyDecision()
Definition: constraint_solver.cc:1174
operations_research::Search::ProgressPercent
int ProgressPercent()
Definition: constraint_solver.cc:1322
operations_research::Search::set_search_depth
void set_search_depth(int d)
Definition: constraint_solver.cc:1036
ConstraintSolverFailsHere
void ConstraintSolverFailsHere()
Definition: constraint_solver.cc:94
operations_research::Trace::SetValues
void SetValues(IntVar *const var, const std::vector< int64 > &values) override
Definition: constraint_solver.cc:3015
operations_research::Search::EndFail
void EndFail()
Definition: constraint_solver.cc:1241
operations_research::BuildDemonProfiler
DemonProfiler * BuildDemonProfiler(Solver *const solver)
Definition: demon_profiler.cc:440
operations_research::Search::RestartSearch
void RestartSearch()
Definition: constraint_solver.cc:1210
file.h
operations_research::RestoreBoolValue
void RestoreBoolValue(IntVar *const var)
Definition: expressions.cc:6346
operations_research::Trace::SetEndRange
void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max) override
Definition: constraint_solver.cc:3047
operations_research::LocalSearchMonitor::BeginAcceptNeighbor
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
operations_research::Search::AcceptNeighbor
void AcceptNeighbor()
Definition: constraint_solver.cc:1301
operations_research::StateMarker
Definition: constraint_solver.cc:443
a
int64 a
Definition: constraint_solver/table.cc:42
operations_research::LocalSearchOperator
The base class for all local search operators.
Definition: constraint_solveri.h:805
operations_research::PropagationMonitor::RemoveValues
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
operations_research::Search::SetBranchSelector
void SetBranchSelector(Solver::BranchSelector bs)
Definition: constraint_solver.cc:1141
constraint_solver.h
operations_research::Trace::SetEndMax
void SetEndMax(IntervalVar *const var, int64 new_max) override
Definition: constraint_solver.cc:3043
operations_research::Trace::RankNotFirst
void RankNotFirst(SequenceVar *const var, int index) override
Definition: constraint_solver.cc:3074
operations_research::StateMarker::StateMarker
StateMarker(Solver::MarkerType t, const StateInfo &info)
Definition: constraint_solver.cc:468
operations_research::Trail::Trail
Trail(int block_size, ConstraintSolverParameters::TrailCompression compression_level)
Definition: constraint_solver.cc:733
operations_research::Trail::rev_bools_
std::vector< bool * > rev_bools_
Definition: constraint_solver.cc:723
operations_research::Trace::RemoveInterval
void RemoveInterval(IntVar *const var, int64 imin, int64 imax) override
Definition: constraint_solver.cc:3011
operations_research::Search::RightMove
void RightMove()
Definition: constraint_solver.cc:1028
operations_research::Trace::RegisterDemon
void RegisterDemon(Demon *const demon) override
Definition: constraint_solver.cc:2937
operations_research::GetProcessMemoryUsage
int64 GetProcessMemoryUsage()
Definition: sysinfo.cc:75
operations_research::Trace::SetDurationMin
void SetDurationMin(IntervalVar *const var, int64 new_min) override
Definition: constraint_solver.cc:3052
operations_research::Trace::RankFirst
void RankFirst(SequenceVar *const var, int index) override
SequenceVar modifiers.
Definition: constraint_solver.cc:3070
operations_research::BuildLocalSearchProfiler
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
Definition: local_search.cc:3561
gtl::FindOrNull
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:41
operations_research::Search::set_backtrack_at_the_end_of_the_search
void set_backtrack_at_the_end_of_the_search(bool restore)
Definition: constraint_solver.cc:1032
operations_research::Search::Clear
void Clear()
Definition: constraint_solver.cc:1187
operations_research::Search::decision_builder
DecisionBuilder * decision_builder() const
Definition: constraint_solver.cc:1019
operations_research::InstallLocalSearchProfiler
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
Definition: local_search.cc:3557
operations_research::Trace::SetStartMax
void SetStartMax(IntervalVar *const var, int64 new_max) override
Definition: constraint_solver.cc:3029
uint32
unsigned int uint32
Definition: integral_types.h:38
CP_TRY
#define CP_TRY(search)
Definition: constraint_solver.cc:1094
operations_research::Search::AcceptSolution
bool AcceptSolution()
Definition: constraint_solver.cc:1251
operations_research::LocalSearchMonitorMaster::EndOperatorStart
void EndOperatorStart() override
Definition: constraint_solver.cc:3131
operations_research::PropagationMonitor::SetStartMax
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
operations_research::Trace::Add
void Add(PropagationMonitor *const monitor)
Definition: constraint_solver.cc:3094
operations_research::Search::EndNextDecision
void EndNextDecision(DecisionBuilder *const db, Decision *const d)
Definition: constraint_solver.cc:1219
operations_research::Trace::Trace
Trace(Solver *const s)
Definition: constraint_solver.cc:2908
operations_research::Trail::rev_object_array_memory_
std::vector< BaseObject ** > rev_object_array_memory_
Definition: constraint_solver.cc:729
operations_research::PropagationMonitor::SetPerformed
virtual void SetPerformed(IntervalVar *const var, bool value)=0
operations_research::BuildLocalSearchMonitorMaster
LocalSearchMonitor * BuildLocalSearchMonitorMaster(Solver *const s)
Definition: constraint_solver.cc:3185
operations_research::Search::set_search_left_depth
void set_search_left_depth(int d)
Definition: constraint_solver.cc:1038
operations_research::Search::IncrementUncheckedSolutionCounter
void IncrementUncheckedSolutionCounter()
Definition: constraint_solver.cc:1012
operations_research::PropagationMonitor::RankLast
virtual void RankLast(SequenceVar *const var, int index)=0
operations_research::Trace::SetMin
void SetMin(IntVar *const var, int64 new_min) override
IntVar modifiers.
Definition: constraint_solver.cc:2985
operations_research::LocalSearchMonitorMaster::BeginMakeNextNeighbor
void BeginMakeNextNeighbor(const LocalSearchOperator *op) override
Definition: constraint_solver.cc:3134
operations_research::PropagationMonitor
Definition: constraint_solveri.h:1853
operations_research::PropagationMonitor::PushContext
virtual void PushContext(const std::string &context)=0
ct
const Constraint * ct
Definition: demon_profiler.cc:42
operations_research::Search::LocalOptimum
bool LocalOptimum()
Definition: constraint_solver.cc:1281
operations_research::Queue::Queue
Queue(Solver *const s)
Definition: constraint_solver.cc:212
operations_research::Search::PeriodicCheck
void PeriodicCheck()
Definition: constraint_solver.cc:1318
operations_research::LocalSearchMonitor
Definition: constraint_solveri.h:1917
operations_research::AcceptDelta
bool AcceptDelta(Search *const search, Assignment *delta, Assignment *deltadelta)
Definition: constraint_solver.cc:1341
uint64
uint64_t uint64
Definition: integral_types.h:39
operations_research::LocalSearchMonitorMaster::Install
void Install() override
Definition: constraint_solver.cc:3175
operations_research::LocalSearchMonitor::BeginFiltering
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
operations_research::Trace::SetRange
void SetRange(IntVar *const var, int64 new_min, int64 new_max) override
Definition: constraint_solver.cc:2997
operations_research::Queue::ProcessOneDemon
void ProcessOneDemon(Demon *const demon)
Definition: constraint_solver.cc:235
CP_ON_FAIL
#define CP_ON_FAIL
Definition: constraint_solver.cc:1098
operations_research::Trace::BeginConstraintInitialPropagation
void BeginConstraintInitialPropagation(Constraint *const constraint) override
Propagation events.
Definition: constraint_solver.cc:2912
operations_research::PropagationMonitor::EndProcessingIntegerVariable
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
operations_research::Trail::rev_int64s_
CompressedTrail< int64 > rev_int64s_
Definition: constraint_solver.cc:718
operations_research::Trace::SetMin
void SetMin(IntExpr *const expr, int64 new_min) override
IntExpr modifiers.
Definition: constraint_solver.cc:2966
operations_research::LocalSearchMonitor::LocalSearchMonitor
LocalSearchMonitor(Solver *const solver)
Definition: constraint_solver.cc:2892
operations_research::Queue
Definition: constraint_solver.cc:208
operations_research::Search::CheckFail
void CheckFail()
Definition: constraint_solver.cc:1043
operations_research::LocalSearchMonitorMaster::BeginOperatorStart
void BeginOperatorStart() override
Local search operator events.
Definition: constraint_solver.cc:3128
operations_research::operator<<
std::ostream & operator<<(std::ostream &out, const BaseObject *const o)
Definition: constraint_solver.cc:2481
DEFINE_int64
DEFINE_int64(cp_random_seed, 12345, "Random seed used in several (but not all) random number " "generators used by the CP solver. Use -1 to auto-generate an" "undeterministic random seed.")
operations_research::Queue::Freeze
void Freeze()
Definition: constraint_solver.cc:224
operations_research::AcceptUncheckedNeighbor
void AcceptUncheckedNeighbor(Search *const search)
Definition: constraint_solver.cc:1348
operations_research::Search::unchecked_solution_counter
int64 unchecked_solution_counter() const
Definition: constraint_solver.cc:1013
operations_research::Search::Search
Search(Solver *const s)
Definition: constraint_solver.cc:948
operations_research::Queue::Process
void Process()
Definition: constraint_solver.cc:254
operations_research::Trail::rev_memory_array_
std::vector< void ** > rev_memory_array_
Definition: constraint_solver.cc:731
operations_research::StateInfo::ptr_info
void * ptr_info
Definition: constraint_solver.cc:436
operations_research::Trail::rev_memory_
std::vector< void * > rev_memory_
Definition: constraint_solver.cc:730
operations_research::PropagationMonitor::RankSequence
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
operations_research::PropagationMonitor::SetEndMin
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
operations_research::Search::left_search_depth
int left_search_depth() const
Definition: constraint_solver.cc:1037
operations_research::Queue::AddConstraint
void AddConstraint(Constraint *const c)
Definition: constraint_solver.cc:369
operations_research::PropagationMonitor::StartProcessingIntegerVariable
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
operations_research::Trace::~Trace
~Trace() override
Definition: constraint_solver.cc:2910
operations_research::LocalSearchMonitor::BeginOperatorStart
virtual void BeginOperatorStart()=0
Local search operator events.
operations_research::Queue::reset_action_on_fail
void reset_action_on_fail()
Definition: constraint_solver.cc:364
operations_research::Search::~Search
~Search()
Definition: constraint_solver.cc:983
operations_research::Queue::EnqueueVar
void EnqueueVar(Demon *const demon)
Definition: constraint_solver.cc:311
operations_research::Trace::SetEndMin
void SetEndMin(IntervalVar *const var, int64 new_min) override
Definition: constraint_solver.cc:3039
operations_research::Search::AcceptDelta
bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
Definition: constraint_solver.cc:1291
operations_research::StateInfo::StateInfo
StateInfo()
Definition: constraint_solver.cc:411
operations_research::Search::push_monitor
void push_monitor(SearchMonitor *const m)
Definition: constraint_solver.cc:1181
operations_research::PropagationMonitor::RemoveInterval
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
operations_research::Search::IsUncheckedSolutionLimitReached
bool IsUncheckedSolutionLimitReached()
Definition: constraint_solver.cc:1309
operations_research::Search::search_context
std::string search_context() const
Definition: constraint_solver.cc:1051
operations_research::Search::BeginNextDecision
void BeginNextDecision(DecisionBuilder *const db)
Definition: constraint_solver.cc:1214
operations_research::LocalSearchFilter
Local Search Filters are used for fast neighbor pruning.
Definition: constraint_solveri.h:1724
stl_util.h
operations_research::PropagationMonitor::SetEndRange
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
operations_research::Trail::rev_doubles_
CompressedTrail< double > rev_doubles_
Definition: constraint_solver.cc:720
operations_research::SimpleRevFIFO< Demon * >
operations_research::BuildTrace
PropagationMonitor * BuildTrace(Solver *const s)
Definition: constraint_solver.cc:3110
operations_research::Search::backtrack_at_the_end_of_the_search
bool backtrack_at_the_end_of_the_search() const
Definition: constraint_solver.cc:1029
operations_research::PropagationMonitor::SetValues
virtual void SetValues(IntVar *const var, const std::vector< int64 > &values)=0
operations_research::LocalSearchMonitorMaster::EndAcceptNeighbor
void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
Definition: constraint_solver.cc:3154
operations_research::StateInfo::left_depth
int left_depth
Definition: constraint_solver.cc:439
operations_research::PropagationMonitor::Install
void Install() override
Install itself on the solver.
Definition: constraint_solver.cc:2886
DEFINE_int32
DEFINE_int32(cp_max_edge_finder_size, 50, "Do not post the edge finder in the cumulative constraints if " "it contains more than this number of tasks")
operations_research::PropagationMonitor::SetDurationMax
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
operations_research::Trail::rev_bool_value_
std::vector< bool > rev_bool_value_
Definition: constraint_solver.cc:724
operations_research::Trace::Install
void Install() override
Definition: constraint_solver.cc:3102
DEFINE_bool
DEFINE_bool(cp_trace_propagation, false, "Trace propagation events (constraint and demon executions," " variable modifications).")
operations_research::Trace::SetMax
void SetMax(IntExpr *const expr, int64 new_max) override
Definition: constraint_solver.cc:2972
operations_research::Trail::rev_int64_memory_
std::vector< int64 * > rev_int64_memory_
Definition: constraint_solver.cc:726
operations_research::Trail::rev_double_memory_
std::vector< double * > rev_double_memory_
Definition: constraint_solver.cc:727
operations_research::Search::should_finish
bool should_finish() const
Definition: constraint_solver.cc:1042
operations_research::LocalSearchMonitor::EndAcceptNeighbor
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
delta
int64 delta
Definition: resource.cc:1684
operations_research::Trace::EndProcessingIntegerVariable
void EndProcessingIntegerVariable(IntVar *const var) override
Definition: constraint_solver.cc:2953
operations_research::sat::Solve
CpSolverResponse Solve(const CpModelProto &model_proto)
Solves the given CpModelProto and returns an instance of CpSolverResponse.
Definition: cp_model_solver.cc:3150
b
int64 b
Definition: constraint_solver/table.cc:43
operations_research::Search::BeginFail
void BeginFail()
Definition: constraint_solver.cc:1239
operations_research::LocalSearchMonitorMaster::EndFiltering
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
Definition: constraint_solver.cc:3162
operations_research::Trace::EndNestedConstraintInitialPropagation
void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
Definition: constraint_solver.cc:2930
operations_research::Trace::SetValue
void SetValue(IntVar *const var, int64 value) override
Definition: constraint_solver.cc:3007
DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:29
operations_research::Search::Accept
void Accept(ModelVisitor *const visitor) const
Definition: constraint_solver.cc:1330
operations_research::Trail::rev_ints_
CompressedTrail< int > rev_ints_
Definition: constraint_solver.cc:717
operations_research::PropagationMonitor::PopContext
virtual void PopContext()=0
operations_research::Search::AcceptUncheckedNeighbor
void AcceptUncheckedNeighbor()
Definition: constraint_solver.cc:1305
operations_research::Search::set_should_restart
void set_should_restart(bool s)
Definition: constraint_solver.cc:1039
operations_research::LocalSearchMonitorMaster::BeginFiltering
void BeginFiltering(const LocalSearchFilter *filter) override
Definition: constraint_solver.cc:3159
next
Block * next
Definition: constraint_solver.cc:667
selector_
BaseVariableAssignmentSelector *const selector_
Definition: search.cc:1850
gtl::STLDeleteElements
void STLDeleteElements(T *container)
Definition: stl_util.h:372
operations_research::LocalSearchMonitor::Install
void Install() override
Install itself on the solver.
Definition: constraint_solver.cc:2899
operations_research::Trace::SetMax
void SetMax(IntVar *const var, int64 new_max) override
Definition: constraint_solver.cc:2991
operations_research::LocalOptimumReached
bool LocalOptimumReached(Search *const search)
Definition: constraint_solver.cc:1337
operations_research::Queue::~Queue
~Queue()
Definition: constraint_solver.cc:222
operations_research::LocalSearchMonitorMaster
Definition: constraint_solver.cc:3123
operations_research::StateInfo::StateInfo
StateInfo(void *pinfo, int iinfo, int d, int ld)
Definition: constraint_solver.cc:423
operations_research::Trail::rev_object_memory_
std::vector< BaseObject * > rev_object_memory_
Definition: constraint_solver.cc:728
operations_research::Search::set_search_context
void set_search_context(const std::string &search_context)
Definition: constraint_solver.cc:1048
operations_research::PropagationMonitor::RemoveValue
virtual void RemoveValue(IntVar *const var, int64 value)=0
operations_research::StateInfo::depth
int depth
Definition: constraint_solver.cc:438
operations_research::Trail::BacktrackTo
void BacktrackTo(StateMarker *m)
Definition: constraint_solver.cc:741
operations_research::StateInfo
Definition: constraint_solver.cc:408
operations_research::Trail::rev_int_memory_
std::vector< int * > rev_int_memory_
Definition: constraint_solver.cc:725
operations_research::Queue::stamp
uint64 stamp() const
Definition: constraint_solver.cc:352
operations_research::Search::should_restart
bool should_restart() const
Definition: constraint_solver.cc:1040
operations_research::PropagationMonitor::RankNotFirst
virtual void RankNotFirst(SequenceVar *const var, int index)=0
operations_research::LocalSearchMonitor::BeginMakeNextNeighbor
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
operations_research::LocalSearchMonitorMaster::EndMakeNextNeighbor
void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta) override
Definition: constraint_solver.cc:3137
operations_research::Search::set_created_by_solve
void set_created_by_solve(bool c)
Definition: constraint_solver.cc:1020
operations_research::Trace::RemoveValues
void RemoveValues(IntVar *const var, const std::vector< int64 > &values) override
Definition: constraint_solver.cc:3019
commandlineflags.h
operations_research::BuildPrintTrace
PropagationMonitor * BuildPrintTrace(Solver *const s)
Definition: trace.cc:874
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:107
MemoryUsage
int64 MemoryUsage(int unused)
Definition: base/sysinfo.h:24
operations_research::StateInfo::StateInfo
StateInfo(void *pinfo, int iinfo)
Definition: constraint_solver.cc:417
name
const std::string name
Definition: default_search.cc:807
operations_research::Trace
Definition: constraint_solver.cc:2906
operations_research::PropagationMonitor::SetEndMax
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
operations_research::Queue::Unfreeze
void Unfreeze()
Definition: constraint_solver.cc:229
operations_research::Search::created_by_solve
bool created_by_solve() const
Definition: constraint_solver.cc:1021
gtl::ContainsKey
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:170
operations_research::Trace::BeginDemonRun
void BeginDemonRun(Demon *const demon) override
Definition: constraint_solver.cc:2941
operations_research::Queue::set_variable_to_clean_on_fail
void set_variable_to_clean_on_fail(IntVar *var)
Definition: constraint_solver.cc:359
operations_research::Queue::kTestPeriod
static constexpr int64 kTestPeriod
Definition: constraint_solver.cc:210
operations_research::PropagationMonitor::RankNotLast
virtual void RankNotLast(SequenceVar *const var, int index)=0