00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stddef.h>
00015 #include <algorithm>
00016 #include "base/hash.h"
00017 #include <string>
00018 #include <utility>
00019 #include <vector>
00020
00021 #include "base/callback.h"
00022 #include "base/integral_types.h"
00023 #include "base/logging.h"
00024 #include "base/scoped_ptr.h"
00025 #include "base/concise_iterator.h"
00026 #include "base/map-util.h"
00027 #include "base/stl_util.h"
00028 #include "base/hash.h"
00029 #include "constraint_solver/constraint_solver.h"
00030 #include "constraint_solver/constraint_solveri.h"
00031 #include "constraint_solver/model.pb.h"
00032 #include "constraint_solver/search_limit.pb.h"
00033 #include "util/tuple_set.h"
00034 #include "util/vector_map.h"
00035
00036 namespace operations_research {
00037
00038
00039
00040
00041
00042 class CPModelLoader {
00043 public:
00044 explicit CPModelLoader(Solver* const solver) : solver_(solver) {}
00045 ~CPModelLoader() {}
00046
00047 Solver* solver() const { return solver_; }
00048
00049
00050
00051 bool BuildFromProto(const CPIntegerExpressionProto& proto);
00052
00053 Constraint* BuildFromProto(const CPConstraintProto& proto);
00054
00055
00056 bool BuildFromProto(const CPIntervalVariableProto& proto);
00057
00058
00059 bool BuildFromProto(const CPSequenceVariableProto& proto);
00060
00061
00062 IntExpr* IntegerExpression(int index) const;
00063
00064 IntervalVar* IntervalVariable(int index) const;
00065
00066 bool ScanOneArgument(int type_index,
00067 const CPArgumentProto& arg_proto,
00068 int64* to_fill);
00069
00070 bool ScanOneArgument(int type_index,
00071 const CPArgumentProto& arg_proto ,
00072 IntExpr** to_fill);
00073
00074 bool ScanOneArgument(int type_index,
00075 const CPArgumentProto& arg_proto,
00076 std::vector<int64>* to_fill);
00077
00078 bool ScanOneArgument(int type_index,
00079 const CPArgumentProto& arg_proto,
00080 IntTupleSet* to_fill);
00081
00082 bool ScanOneArgument(int type_index,
00083 const CPArgumentProto& arg_proto,
00084 std::vector<IntVar*>* to_fill);
00085
00086 bool ScanOneArgument(int type_index,
00087 const CPArgumentProto& arg_proto,
00088 IntervalVar** to_fill);
00089
00090 bool ScanOneArgument(int type_index,
00091 const CPArgumentProto& arg_proto,
00092 std::vector<IntervalVar*>* to_fill);
00093
00094 bool ScanOneArgument(int type_index,
00095 const CPArgumentProto& arg_proto,
00096 SequenceVar** to_fill);
00097
00098 bool ScanOneArgument(int type_index,
00099 const CPArgumentProto& arg_proto,
00100 std::vector<SequenceVar*>* to_fill);
00101
00102 template <class P, class A> bool ScanArguments(const string& type,
00103 const P& proto,
00104 A* to_fill) {
00105 const int index = tags_.Index(type);
00106 for (int i = 0; i < proto.arguments_size(); ++i) {
00107 if (ScanOneArgument(index, proto.arguments(i), to_fill)) {
00108 return true;
00109 }
00110 }
00111 return false;
00112 }
00113
00114 int TagIndex(const string& tag) const { return tags_.Index(tag); }
00115
00116 void AddTag(const string& tag) { tags_.Add(tag); }
00117
00118 private:
00119 Solver* const solver_;
00120 std::vector<IntExpr*> expressions_;
00121 std::vector<IntervalVar*> intervals_;
00122 std::vector<SequenceVar*> sequences_;
00123 VectorMap<string> tags_;
00124 };
00125
00126 namespace {
00127
00128
00129
00130
00131
00132
00133
00134 class FirstPassVisitor : public ModelVisitor {
00135 public:
00136 FirstPassVisitor() {}
00137 virtual ~FirstPassVisitor() {}
00138
00139
00140 virtual void BeginVisitModel(const string& solver_name) {
00141
00142 expression_map_.clear();
00143 delegate_map_.clear();
00144 expression_list_.clear();
00145 constraint_list_.clear();
00146 interval_list_.clear();
00147 sequence_list_.clear();
00148 }
00149
00150 virtual void EndVisitConstraint(const string& type_name,
00151 const Constraint* const constraint) {
00152 Register(constraint);
00153 }
00154
00155 virtual void EndVisitIntegerExpression(const string& type_name,
00156 const IntExpr* const expression) {
00157 Register(expression);
00158 }
00159
00160 virtual void VisitIntegerVariable(const IntVar* const variable,
00161 const IntExpr* const delegate) {
00162 if (delegate != NULL) {
00163 delegate->Accept(this);
00164 delegate_map_[variable] = delegate;
00165 }
00166 Register(variable);
00167 }
00168
00169 virtual void VisitIntegerVariable(const IntVar* const variable,
00170 const string& operation,
00171 int64 value,
00172 const IntVar* const delegate) {
00173 delegate->Accept(this);
00174 delegate_map_[variable] = delegate;
00175 Register(variable);
00176 }
00177
00178 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00179 const string& operation,
00180 const IntervalVar* const delegate) {
00181 if (delegate != NULL) {
00182 delegate->Accept(this);
00183 }
00184 Register(variable);
00185 }
00186
00187 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00188 const string& operation,
00189 const IntervalVar* const * delegates,
00190 int size) {
00191 for (int i = 0; i < size; ++i) {
00192 delegates[i]->Accept(this);
00193 }
00194 Register(variable);
00195 }
00196
00197 virtual void VisitSequenceVariable(const SequenceVar* const sequence) {
00198 for (int i = 0; i < sequence->size(); ++i) {
00199 sequence->Interval(i)->Accept(this);
00200 }
00201 Register(sequence);
00202 }
00203
00204
00205 virtual void VisitIntegerExpressionArgument(
00206 const string& arg_name,
00207 const IntExpr* const argument) {
00208 VisitSubArgument(argument);
00209 }
00210
00211 virtual void VisitIntegerVariableArrayArgument(
00212 const string& arg_name,
00213 const IntVar* const * arguments,
00214 int size) {
00215 for (int i = 0; i < size; ++i) {
00216 VisitSubArgument(arguments[i]);
00217 }
00218 }
00219
00220
00221 virtual void VisitIntervalArgument(const string& arg_name,
00222 const IntervalVar* const argument) {
00223 VisitSubArgument(argument);
00224 }
00225
00226 virtual void VisitIntervalArrayArgument(const string& arg_name,
00227 const IntervalVar* const * arguments,
00228 int size) {
00229 for (int i = 0; i < size; ++i) {
00230 VisitSubArgument(arguments[i]);
00231 }
00232 }
00233
00234
00235 virtual void VisitSequenceArgument(const string& arg_name,
00236 const SequenceVar* const argument) {
00237 VisitSubArgument(argument);
00238 }
00239
00240 virtual void VisitSequenceArrayArgument(const string& arg_name,
00241 const SequenceVar* const * arguments,
00242 int size) {
00243 for (int i = 0; i < size; ++i) {
00244 VisitSubArgument(arguments[i]);
00245 }
00246 }
00247
00248
00249 const hash_map<const IntExpr*, int>& expression_map() const {
00250 return expression_map_;
00251 }
00252 const hash_map<const IntervalVar*, int>& interval_map() const {
00253 return interval_map_;
00254 }
00255 const hash_map<const SequenceVar*, int>& sequence_map() const {
00256 return sequence_map_;
00257 }
00258 const hash_map<const IntVar*, const IntExpr*>& delegate_map() const {
00259 return delegate_map_;
00260 }
00261 const std::vector<const IntExpr*>& expression_list() const {
00262 return expression_list_;
00263 }
00264 const std::vector<const Constraint*>& constraint_list() const {
00265 return constraint_list_;
00266 }
00267 const std::vector<const IntervalVar*>& interval_list() const {
00268 return interval_list_;
00269 }
00270 const std::vector<const SequenceVar*>& sequence_list() const {
00271 return sequence_list_;
00272 }
00273
00274 private:
00275 void Register(const IntExpr* const expression) {
00276 if (!ContainsKey(expression_map_, expression)) {
00277 const int index = expression_map_.size();
00278 CHECK_EQ(index, expression_list_.size());
00279 expression_map_[expression] = index;
00280 expression_list_.push_back(expression);
00281 }
00282 }
00283
00284 void Register(const Constraint* const constraint) {
00285 constraint_list_.push_back(constraint);
00286 }
00287
00288 void Register(const IntervalVar* const interval) {
00289 if (!ContainsKey(interval_map_, interval)) {
00290 const int index = interval_map_.size();
00291 CHECK_EQ(index, interval_list_.size());
00292 interval_map_[interval] = index;
00293 interval_list_.push_back(interval);
00294 }
00295 }
00296
00297 void Register(const SequenceVar* const sequence) {
00298 if (!ContainsKey(sequence_map_, sequence)) {
00299 const int index = sequence_map_.size();
00300 CHECK_EQ(index, sequence_list_.size());
00301 sequence_map_[sequence] = index;
00302 sequence_list_.push_back(sequence);
00303 }
00304 }
00305
00306 void VisitSubArgument(const IntExpr* const expression) {
00307 if (!ContainsKey(expression_map_, expression)) {
00308 expression->Accept(this);
00309 }
00310 }
00311
00312 void VisitSubArgument(const IntervalVar* const interval) {
00313 if (!ContainsKey(interval_map_, interval)) {
00314 interval->Accept(this);
00315 }
00316 }
00317
00318 void VisitSubArgument(const SequenceVar* const sequence) {
00319 if (!ContainsKey(sequence_map_, sequence)) {
00320 sequence->Accept(this);
00321 }
00322 }
00323
00324 const string filename_;
00325 hash_map<const IntExpr*, int> expression_map_;
00326 hash_map<const IntervalVar*, int> interval_map_;
00327 hash_map<const SequenceVar*, int> sequence_map_;
00328 hash_map<const IntVar*, const IntExpr*> delegate_map_;
00329 std::vector<const IntExpr*> expression_list_;
00330 std::vector<const Constraint*> constraint_list_;
00331 std::vector<const IntervalVar*> interval_list_;
00332 std::vector<const SequenceVar*> sequence_list_;
00333 };
00334
00335
00336
00337 class ArgumentHolder {
00338 public:
00339 template <class P> void ExportToProto(VectorMap<string>* const tags,
00340 P* const proto) const {
00341 for (ConstIter<hash_map<string, int64> > it(integer_argument_);
00342 !it.at_end();
00343 ++it) {
00344 CPArgumentProto* const arg_proto = proto->add_arguments();
00345 arg_proto->set_argument_index(tags->Add(it->first));
00346 arg_proto->set_integer_value(it->second);
00347 }
00348
00349 for (ConstIter<hash_map<string, std::vector<int64> > > it(
00350 integer_array_argument_); !it.at_end(); ++it) {
00351 CPArgumentProto* const arg_proto = proto->add_arguments();
00352 arg_proto->set_argument_index(tags->Add(it->first));
00353 for (int i = 0; i < it->second.size(); ++i) {
00354 arg_proto->add_integer_array(it->second[i]);
00355 }
00356 }
00357
00358 for (ConstIter<hash_map<string, std::pair<int, std::vector<int64> > > > it(
00359 integer_matrix_argument_); !it.at_end(); ++it) {
00360 CPArgumentProto* const arg_proto = proto->add_arguments();
00361 arg_proto->set_argument_index(tags->Add(it->first));
00362 CPIntegerMatrixProto* const matrix_proto =
00363 arg_proto->mutable_integer_matrix();
00364 const int columns = it->second.first;
00365 CHECK_GT(columns, 0);
00366 const int rows = it->second.second.size() / columns;
00367 matrix_proto->set_rows(rows);
00368 matrix_proto->set_columns(columns);
00369 for (int i = 0; i < it->second.second.size(); ++i) {
00370 matrix_proto->add_values(it->second.second[i]);
00371 }
00372 }
00373
00374 for (ConstIter<hash_map<string, int> > it(
00375 integer_expression_argument_); !it.at_end(); ++it) {
00376 CPArgumentProto* const arg_proto = proto->add_arguments();
00377 arg_proto->set_argument_index(tags->Add(it->first));
00378 arg_proto->set_integer_expression_index(it->second);
00379 }
00380
00381 for (ConstIter<hash_map<string, std::vector<int> > > it(
00382 integer_variable_array_argument_); !it.at_end(); ++it) {
00383 CPArgumentProto* const arg_proto = proto->add_arguments();
00384 arg_proto->set_argument_index(tags->Add(it->first));
00385 for (int i = 0; i < it->second.size(); ++i) {
00386 arg_proto->add_integer_expression_array(it->second[i]);
00387 }
00388 }
00389
00390 for (ConstIter<hash_map<string, int> > it(interval_argument_);
00391 !it.at_end();
00392 ++it) {
00393 CPArgumentProto* const arg_proto = proto->add_arguments();
00394 arg_proto->set_argument_index(tags->Add(it->first));
00395 arg_proto->set_interval_index(it->second);
00396 }
00397
00398 for (ConstIter<hash_map<string, std::vector<int> > > it(
00399 interval_array_argument_); !it.at_end(); ++it) {
00400 CPArgumentProto* const arg_proto = proto->add_arguments();
00401 arg_proto->set_argument_index(tags->Add(it->first));
00402 for (int i = 0; i < it->second.size(); ++i) {
00403 arg_proto->add_interval_array(it->second[i]);
00404 }
00405 }
00406
00407 for (ConstIter<hash_map<string, int> > it(sequence_argument_);
00408 !it.at_end();
00409 ++it) {
00410 CPArgumentProto* const arg_proto = proto->add_arguments();
00411 arg_proto->set_argument_index(tags->Add(it->first));
00412 arg_proto->set_sequence_index(it->second);
00413 }
00414
00415 for (ConstIter<hash_map<string, std::vector<int> > > it(
00416 sequence_array_argument_); !it.at_end(); ++it) {
00417 CPArgumentProto* const arg_proto = proto->add_arguments();
00418 arg_proto->set_argument_index(tags->Add(it->first));
00419 for (int i = 0; i < it->second.size(); ++i) {
00420 arg_proto->add_sequence_array(it->second[i]);
00421 }
00422 }
00423 }
00424
00425 const string& type_name() const {
00426 return type_name_;
00427 }
00428
00429 void set_type_name(const string& type_name) {
00430 type_name_ = type_name;
00431 }
00432
00433 void set_integer_argument(const string& arg_name, int64 value) {
00434 integer_argument_[arg_name] = value;
00435 }
00436
00437 void set_integer_array_argument(const string& arg_name,
00438 const int64* const values,
00439 int size) {
00440 for (int i = 0; i < size; ++i) {
00441 integer_array_argument_[arg_name].push_back(values[i]);
00442 }
00443 }
00444
00445 void set_integer_matrix_argument(const string& arg_name,
00446 const IntTupleSet& values) {
00447 const int rows = values.NumTuples();
00448 const int columns = values.Arity();
00449 std::pair<int, std::vector<int64> > matrix = make_pair(columns, std::vector<int64>());
00450 integer_matrix_argument_[arg_name] = matrix;
00451 std::vector<int64>* const vals = &integer_matrix_argument_[arg_name].second;
00452 for (int i = 0; i < rows; ++i) {
00453 for (int j = 0; j < columns; ++j) {
00454 vals->push_back(values.Value(i, j));
00455 }
00456 }
00457 }
00458
00459 void set_integer_expression_argument(const string& arg_name, int index) {
00460 integer_expression_argument_[arg_name] = index;
00461 }
00462
00463 void set_integer_variable_array_argument(const string& arg_name,
00464 const int* const indices,
00465 int size) {
00466 for (int i = 0; i < size; ++i) {
00467 integer_variable_array_argument_[arg_name].push_back(indices[i]);
00468 }
00469 }
00470
00471 void set_interval_argument(const string& arg_name, int index) {
00472 interval_argument_[arg_name] = index;
00473 }
00474
00475 void set_interval_array_argument(const string& arg_name,
00476 const int* const indices,
00477 int size) {
00478 for (int i = 0; i < size; ++i) {
00479 interval_array_argument_[arg_name].push_back(indices[i]);
00480 }
00481 }
00482
00483 void set_sequence_argument(const string& arg_name, int index) {
00484 sequence_argument_[arg_name] = index;
00485 }
00486
00487 void set_sequence_array_argument(const string& arg_name,
00488 const int* const indices,
00489 int size) {
00490 for (int i = 0; i < size; ++i) {
00491 sequence_array_argument_[arg_name].push_back(indices[i]);
00492 }
00493 }
00494
00495 int64 FindIntegerArgumentWithDefault(const string& arg_name, int64 def) {
00496 return FindWithDefault(integer_argument_, arg_name, def);
00497 }
00498
00499 int64 FindIntegerArgumentOrDie(const string& arg_name) {
00500 return FindOrDie(integer_argument_, arg_name);
00501 }
00502
00503 int64 FindIntegerExpressionArgumentOrDie(const string& arg_name) {
00504 return FindOrDie(integer_expression_argument_, arg_name);
00505 }
00506
00507 private:
00508 string type_name_;
00509 hash_map<string, int> integer_expression_argument_;
00510 hash_map<string, int64> integer_argument_;
00511 hash_map<string, int> interval_argument_;
00512 hash_map<string, int> sequence_argument_;
00513 hash_map<string, std::vector<int64> > integer_array_argument_;
00514 hash_map<string, std::pair<int, std::vector<int64> > > integer_matrix_argument_;
00515 hash_map<string, std::vector<int> > integer_variable_array_argument_;
00516 hash_map<string, std::vector<int> > interval_array_argument_;
00517 hash_map<string, std::vector<int> > sequence_array_argument_;
00518 };
00519
00520
00521
00522 static const int kModelVersion = 1;
00523
00524
00525
00526
00527 class SecondPassVisitor : public ModelVisitor {
00528 public:
00529 SecondPassVisitor(const FirstPassVisitor& first_pass,
00530 CPModelProto* const model_proto)
00531 : expression_map_(first_pass.expression_map()),
00532 interval_map_(first_pass.interval_map()),
00533 sequence_map_(first_pass.sequence_map()),
00534 delegate_map_(first_pass.delegate_map()),
00535 expression_list_(first_pass.expression_list()),
00536 constraint_list_(first_pass.constraint_list()),
00537 interval_list_(first_pass.interval_list()),
00538 sequence_list_(first_pass.sequence_list()),
00539 model_proto_(model_proto) {}
00540
00541 virtual ~SecondPassVisitor() {}
00542
00543 virtual void BeginVisitModel(const string& model_name) {
00544 model_proto_->set_model(model_name);
00545 model_proto_->set_version(kModelVersion);
00546 PushArgumentHolder();
00547 for (ConstIter<std::vector<const IntExpr*> > it(expression_list_);
00548 !it.at_end();
00549 ++it) {
00550 (*it)->Accept(this);
00551 }
00552
00553 for (ConstIter<std::vector<const IntervalVar*> > it(interval_list_);
00554 !it.at_end();
00555 ++it) {
00556 (*it)->Accept(this);
00557 }
00558
00559 for (ConstIter<std::vector<const SequenceVar*> > it(sequence_list_);
00560 !it.at_end();
00561 ++it) {
00562 (*it)->Accept(this);
00563 }
00564 }
00565
00566 virtual void EndVisitModel(const string& model_name) {
00567 for (ConstIter<std::vector<ArgumentHolder*> > it(extensions_);
00568 !it.at_end();
00569 ++it) {
00570 WriteModelExtension(*it);
00571 }
00572 PopArgumentHolder();
00573
00574 for (int i = 0; i < tags_.size(); ++i) {
00575 model_proto_->add_tags(tags_.Element(i));
00576 }
00577 }
00578
00579 virtual void BeginVisitConstraint(const string& type_name,
00580 const Constraint* const constraint) {
00581 PushArgumentHolder();
00582 }
00583
00584 virtual void EndVisitConstraint(const string& type_name,
00585 const Constraint* const constraint) {
00586
00587 if (constraint->IsCastConstraint()) {
00588 return;
00589 }
00590
00591 const int index = model_proto_->constraints_size();
00592 CPConstraintProto* const constraint_proto = model_proto_->add_constraints();
00593 ExportToProto(constraint, constraint_proto, type_name, index);
00594 PopArgumentHolder();
00595 }
00596
00597 virtual void BeginVisitIntegerExpression(const string& type_name,
00598 const IntExpr* const expression) {
00599 PushArgumentHolder();
00600 }
00601
00602 virtual void EndVisitIntegerExpression(const string& type_name,
00603 const IntExpr* const expression) {
00604 const int index = model_proto_->expressions_size();
00605 CPIntegerExpressionProto* const expression_proto =
00606 model_proto_->add_expressions();
00607 ExportToProto(expression, expression_proto, type_name, index);
00608 PopArgumentHolder();
00609 }
00610
00611 virtual void BeginVisitExtension(const string& type_name) {
00612 PushExtension(type_name);
00613 }
00614
00615 virtual void EndVisitExtension(const string& type_name) {
00616 PopAndSaveExtension();
00617 }
00618
00619 virtual void VisitIntegerArgument(const string& arg_name, int64 value) {
00620 top()->set_integer_argument(arg_name, value);
00621 }
00622
00623 virtual void VisitIntegerArrayArgument(const string& arg_name,
00624 const int64* const values,
00625 int size) {
00626 top()->set_integer_array_argument(arg_name, values, size);
00627 }
00628
00629 virtual void VisitIntegerMatrixArgument(const string& arg_name,
00630 const IntTupleSet& values) {
00631 top()->set_integer_matrix_argument(arg_name, values);
00632 }
00633
00634 virtual void VisitIntegerExpressionArgument(
00635 const string& arg_name,
00636 const IntExpr* const argument) {
00637 top()->set_integer_expression_argument(arg_name,
00638 FindExpressionIndexOrDie(argument));
00639 }
00640
00641 virtual void VisitIntegerVariableArrayArgument(
00642 const string& arg_name,
00643 const IntVar* const * arguments,
00644 int size) {
00645 std::vector<int> indices;
00646 for (int i = 0; i < size; ++i) {
00647 indices.push_back(FindExpressionIndexOrDie(arguments[i]));
00648 }
00649 top()->set_integer_variable_array_argument(arg_name,
00650 indices.data(),
00651 indices.size());
00652 }
00653
00654 virtual void VisitIntervalArgument(
00655 const string& arg_name,
00656 const IntervalVar* argument) {
00657 top()->set_interval_argument(arg_name, FindIntervalIndexOrDie(argument));
00658 }
00659
00660 virtual void VisitIntervalArrayArgument(
00661 const string& arg_name,
00662 const IntervalVar* const * arguments,
00663 int size) {
00664 std::vector<int> indices;
00665 for (int i = 0; i < size; ++i) {
00666 indices.push_back(FindIntervalIndexOrDie(arguments[i]));
00667 }
00668 top()->set_interval_array_argument(arg_name,
00669 indices.data(),
00670 indices.size());
00671 }
00672
00673 virtual void VisitSequenceArgument(
00674 const string& arg_name,
00675 const SequenceVar* argument) {
00676 top()->set_sequence_argument(arg_name, FindSequenceIndexOrDie(argument));
00677 }
00678
00679 virtual void VisitSequenceArrayArgument(
00680 const string& arg_name,
00681 const SequenceVar* const * arguments,
00682 int size) {
00683 std::vector<int> indices;
00684 for (int i = 0; i < size; ++i) {
00685 indices.push_back(FindSequenceIndexOrDie(arguments[i]));
00686 }
00687 top()->set_sequence_array_argument(arg_name,
00688 indices.data(),
00689 indices.size());
00690 }
00691
00692 virtual void VisitIntegerVariable(const IntVar* const variable,
00693 const IntExpr* const delegate) {
00694 if (delegate != NULL) {
00695 const int index = model_proto_->expressions_size();
00696 CPIntegerExpressionProto* const var_proto =
00697 model_proto_->add_expressions();
00698 var_proto->set_index(index);
00699 var_proto->set_type_index(TagIndex(ModelVisitor::kIntegerVariable));
00700 CPArgumentProto* const sub_proto = var_proto->add_arguments();
00701 sub_proto->set_argument_index(
00702 TagIndex(ModelVisitor::kExpressionArgument));
00703 sub_proto->set_integer_expression_index(
00704 FindExpressionIndexOrDie(delegate));
00705 } else {
00706 const int index = model_proto_->expressions_size();
00707 CPIntegerExpressionProto* const var_proto =
00708 model_proto_->add_expressions();
00709 var_proto->set_index(index);
00710 var_proto->set_type_index(TagIndex(ModelVisitor::kIntegerVariable));
00711 if (variable->HasName()) {
00712 var_proto->set_name(variable->name());
00713 }
00714 if (variable->Size() == variable->Max() - variable->Min() + 1) {
00715
00716 CPArgumentProto* const min_proto = var_proto->add_arguments();
00717 min_proto->set_argument_index(TagIndex(ModelVisitor::kMinArgument));
00718 min_proto->set_integer_value(variable->Min());
00719 CPArgumentProto* const max_proto = var_proto->add_arguments();
00720 max_proto->set_argument_index(TagIndex(ModelVisitor::kMaxArgument));
00721 max_proto->set_integer_value(variable->Max());
00722 } else {
00723
00724 CPArgumentProto* const values_proto = var_proto->add_arguments();
00725 values_proto->set_argument_index(
00726 TagIndex(ModelVisitor::kValuesArgument));
00727 scoped_ptr<IntVarIterator> it(variable->MakeDomainIterator(false));
00728 for (it->Init(); it->Ok(); it->Next()) {
00729 values_proto->add_integer_array(it->Value());
00730 }
00731 }
00732 }
00733 }
00734
00735 virtual void VisitIntegerVariable(const IntVar* const variable,
00736 const string& operation,
00737 int64 value,
00738 const IntVar* const delegate) {
00739 const int index = model_proto_->expressions_size();
00740 CPIntegerExpressionProto* const var_proto =
00741 model_proto_->add_expressions();
00742 var_proto->set_index(index);
00743 var_proto->set_type_index(TagIndex(ModelVisitor::kIntegerVariable));
00744 CPArgumentProto* const sub_proto = var_proto->add_arguments();
00745 sub_proto->set_argument_index(
00746 TagIndex(ModelVisitor::kVariableArgument));
00747 sub_proto->set_integer_expression_index(FindExpressionIndexOrDie(delegate));
00748 CPArgumentProto* const value_proto = var_proto->add_arguments();
00749 value_proto->set_argument_index(TagIndex(operation));
00750 value_proto->set_integer_value(value);
00751 }
00752
00753 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00754 const string& operation,
00755 const IntervalVar* const delegate) {
00756 if (delegate != NULL) {
00757 const int index = model_proto_->intervals_size();
00758 CPIntervalVariableProto* const var_proto = model_proto_->add_intervals();
00759 var_proto->set_index(index);
00760 var_proto->set_type_index(TagIndex(ModelVisitor::kIntervalVariable));
00761 CPArgumentProto* const sub_proto = var_proto->add_arguments();
00762 sub_proto->set_argument_index(TagIndex(operation));
00763 sub_proto->set_interval_index(FindIntervalIndexOrDie(delegate));
00764 } else {
00765 const int index = model_proto_->intervals_size();
00766 CPIntervalVariableProto* const var_proto = model_proto_->add_intervals();
00767 var_proto->set_index(index);
00768 var_proto->set_type_index(TagIndex(ModelVisitor::kIntervalVariable));
00769 if (variable->HasName()) {
00770 var_proto->set_name(variable->name());
00771 }
00772 CPArgumentProto* const start_min_proto = var_proto->add_arguments();
00773 start_min_proto->set_argument_index(
00774 TagIndex(ModelVisitor::kStartMinArgument));
00775 start_min_proto->set_integer_value(variable->StartMin());
00776 CPArgumentProto* const start_max_proto = var_proto->add_arguments();
00777 start_max_proto->set_argument_index(
00778 TagIndex(ModelVisitor::kStartMaxArgument));
00779 start_max_proto->set_integer_value(variable->StartMax());
00780 CPArgumentProto* const end_min_proto = var_proto->add_arguments();
00781 end_min_proto->set_argument_index(
00782 TagIndex(ModelVisitor::kEndMinArgument));
00783 end_min_proto->set_integer_value(variable->EndMin());
00784 CPArgumentProto* const end_max_proto = var_proto->add_arguments();
00785 end_max_proto->set_argument_index(
00786 TagIndex(ModelVisitor::kEndMaxArgument));
00787 end_max_proto->set_integer_value(variable->EndMax());
00788 CPArgumentProto* const duration_min_proto = var_proto->add_arguments();
00789 duration_min_proto->set_argument_index(
00790 TagIndex(ModelVisitor::kDurationMinArgument));
00791 duration_min_proto->set_integer_value(variable->DurationMin());
00792 CPArgumentProto* const duration_max_proto = var_proto->add_arguments();
00793 duration_max_proto->set_argument_index(
00794 TagIndex(ModelVisitor::kDurationMaxArgument));
00795 duration_max_proto->set_integer_value(variable->DurationMax());
00796 CPArgumentProto* const optional_proto = var_proto->add_arguments();
00797 optional_proto->set_argument_index(
00798 TagIndex(ModelVisitor::kOptionalArgument));
00799 optional_proto->set_integer_value(!variable->MustBePerformed());
00800 }
00801 }
00802
00803 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00804 const string& operation,
00805 const IntervalVar* const * delegates,
00806 int size) {
00807 CHECK_NOTNULL(delegates);
00808 CHECK_GT(size, 0);
00809 const int index = model_proto_->intervals_size();
00810 CPIntervalVariableProto* const var_proto = model_proto_->add_intervals();
00811 var_proto->set_index(index);
00812 var_proto->set_type_index(TagIndex(ModelVisitor::kIntervalVariable));
00813 if (variable->HasName()) {
00814 var_proto->set_name(variable->name());
00815 }
00816 CPArgumentProto* const sub_proto = var_proto->add_arguments();
00817 sub_proto->set_argument_index(TagIndex(operation));
00818 for (int i = 0; i < size; ++i) {
00819 sub_proto->add_interval_array(FindIntervalIndexOrDie(delegates[i]));
00820 }
00821 }
00822
00823 virtual void VisitSequenceVariable(const SequenceVar* const sequence) {
00824 const int index = model_proto_->sequences_size();
00825 CPSequenceVariableProto* const var_proto = model_proto_->add_sequences();
00826 var_proto->set_index(index);
00827 var_proto->set_type_index(TagIndex(ModelVisitor::kSequenceVariable));
00828 if (sequence->HasName()) {
00829 var_proto->set_name(sequence->name());
00830 }
00831 CPArgumentProto* const sub_proto = var_proto->add_arguments();
00832 sub_proto->set_argument_index(TagIndex(ModelVisitor::kIntervalsArgument));
00833 for (int i = 0; i < sequence->size(); ++i) {
00834 IntervalVar* const interval = sequence->Interval(i);
00835 sub_proto->add_interval_array(FindIntervalIndexOrDie(interval));
00836 }
00837 }
00838
00839 int TagIndex(const string& tag) {
00840 return tags_.Add(tag);
00841 }
00842
00843 private:
00844 void WriteModelExtension(ArgumentHolder* const holder) {
00845 CHECK_NOTNULL(holder);
00846 if (holder->type_name().compare(kObjectiveExtension) == 0) {
00847 WriteObjective(holder);
00848 } else if (holder->type_name().compare(kSearchLimitExtension) == 0) {
00849 WriteSearchLimit(holder);
00850 } else if (holder->type_name().compare(kVariableGroupExtension) == 0) {
00851 WriteVariableGroup(holder);
00852 } else {
00853 LOG(INFO) << "Unknown model extension :" << holder->type_name();
00854 }
00855 }
00856
00857 void WriteObjective(ArgumentHolder* const holder) {
00858 CHECK_NOTNULL(holder);
00859 const bool maximize = holder->FindIntegerArgumentOrDie(kMaximizeArgument);
00860 const int64 step = holder->FindIntegerArgumentOrDie(kStepArgument);
00861 const int objective_index =
00862 holder->FindIntegerExpressionArgumentOrDie(kExpressionArgument);
00863 CPObjectiveProto* const objective_proto = model_proto_->mutable_objective();
00864 objective_proto->set_maximize(maximize);
00865 objective_proto->set_step(step);
00866 objective_proto->set_objective_index(objective_index);
00867 }
00868
00869 void WriteSearchLimit(ArgumentHolder* const holder) {
00870 CHECK_NOTNULL(holder);
00871 SearchLimitProto* const proto = model_proto_->mutable_search_limit();
00872 proto->set_time(holder->FindIntegerArgumentWithDefault(kTimeLimitArgument,
00873 kint64max));
00874 proto->set_branches(holder->FindIntegerArgumentWithDefault(
00875 kBranchesLimitArgument,
00876 kint64max));
00877 proto->set_failures(holder->FindIntegerArgumentWithDefault(
00878 kFailuresLimitArgument,
00879 kint64max));
00880 proto->set_solutions(holder->FindIntegerArgumentWithDefault(
00881 kSolutionLimitArgument,
00882 kint64max));
00883 proto->set_smart_time_check(holder->FindIntegerArgumentWithDefault(
00884 kSmartTimeCheckArgument,
00885 false));
00886 proto->set_cumulative(holder->FindIntegerArgumentWithDefault(
00887 kCumulativeArgument,
00888 false));
00889 }
00890
00891 void WriteVariableGroup(ArgumentHolder* const holder) {
00892 CPVariableGroup* const group_proto = model_proto_->add_variable_groups();
00893 holder->ExportToProto(&tags_, group_proto);
00894 }
00895
00896 template <class A, class P> void ExportToProto(const A* const argument,
00897 P* const proto,
00898 const string& type_name,
00899 int index) {
00900 CHECK_NOTNULL(proto);
00901 CHECK_NOTNULL(argument);
00902 proto->set_index(index);
00903 proto->set_type_index(TagIndex(type_name));
00904 if (argument->HasName()) {
00905 proto->set_name(argument->name());
00906 }
00907 top()->ExportToProto(&tags_, proto);
00908 for (ConstIter<std::vector<ArgumentHolder*> > it(extensions_);
00909 !it.at_end();
00910 ++it) {
00911 CPExtensionProto* const extension_proto = proto->add_extensions();
00912 extension_proto->set_type_index(TagIndex((*it)->type_name()));
00913 (*it)->ExportToProto(&tags_, extension_proto);
00914 }
00915 }
00916
00917 void PushArgumentHolder() {
00918 holders_.push_back(new ArgumentHolder);
00919 }
00920
00921 void PopArgumentHolder() {
00922 CHECK(!holders_.empty());
00923 delete holders_.back();
00924 holders_.pop_back();
00925 STLDeleteElements(&extensions_);
00926 extensions_.clear();
00927 }
00928
00929 void PushExtension(const string& type_name) {
00930 PushArgumentHolder();
00931 holders_.back()->set_type_name(type_name);
00932 }
00933
00934 void PopAndSaveExtension() {
00935 CHECK(!holders_.empty());
00936 extensions_.push_back(holders_.back());
00937 holders_.pop_back();
00938 }
00939
00940 ArgumentHolder* top() const {
00941 CHECK(!holders_.empty());
00942 return holders_.back();
00943 }
00944
00945 int FindExpressionIndexOrDie(const IntExpr* const expression) const {
00946 return FindOrDie(expression_map_, expression);
00947 }
00948
00949 int FindIntervalIndexOrDie(const IntervalVar* const interval) const {
00950 return FindOrDie(interval_map_, interval);
00951 }
00952
00953 int FindSequenceIndexOrDie(const SequenceVar* const sequence) const {
00954 return FindOrDie(sequence_map_, sequence);
00955 }
00956
00957
00958 hash_map<const IntExpr*, int> expression_map_;
00959 hash_map<const IntervalVar*, int> interval_map_;
00960 hash_map<const SequenceVar*, int> sequence_map_;
00961 hash_map<const IntVar*, const IntExpr*> delegate_map_;
00962 std::vector<const IntExpr*> expression_list_;
00963 std::vector<const Constraint*> constraint_list_;
00964 std::vector<const IntervalVar*> interval_list_;
00965 std::vector<const SequenceVar*> sequence_list_;
00966 CPModelProto* const model_proto_;
00967
00968 std::vector<ArgumentHolder*> holders_;
00969 std::vector<ArgumentHolder*> extensions_;
00970 VectorMap<string> tags_;
00971 };
00972
00973
00974
00975
00976
00977 template <class T> class ArrayWithOffset : public BaseObject {
00978 public:
00979 ArrayWithOffset(int64 index_min, int64 index_max)
00980 : index_min_(index_min),
00981 index_max_(index_max),
00982 values_(new T[index_max - index_min + 1]) {
00983 DCHECK_LE(index_min, index_max);
00984 }
00985
00986 virtual ~ArrayWithOffset() {}
00987
00988 virtual T Evaluate(int64 index) const {
00989 DCHECK_GE(index, index_min_);
00990 DCHECK_LE(index, index_max_);
00991 return values_[index - index_min_];
00992 }
00993
00994 void SetValue(int64 index, T value) {
00995 DCHECK_GE(index, index_min_);
00996 DCHECK_LE(index, index_max_);
00997 values_[index - index_min_] = value;
00998 }
00999
01000 private:
01001 const int64 index_min_;
01002 const int64 index_max_;
01003 scoped_array<T> values_;
01004 };
01005
01006 template <class T> void MakeCallbackFromProto(
01007 CPModelLoader* const builder,
01008 const CPExtensionProto& proto,
01009 int tag_index,
01010 ResultCallback1<T, int64>** callback) {
01011 DCHECK_EQ(tag_index, proto.type_index());
01012 Solver* const solver = builder->solver();
01013 int64 index_min = 0;
01014 CHECK(builder->ScanArguments(ModelVisitor::kMinArgument, proto, &index_min));
01015 int64 index_max = 0;
01016 CHECK(builder->ScanArguments(ModelVisitor::kMaxArgument, proto, &index_max));
01017 std::vector<int64> values;
01018 CHECK(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values));
01019 ArrayWithOffset<T>* const array =
01020 solver->RevAlloc(new ArrayWithOffset<T>(index_min, index_max));
01021 for (int i = index_min; i <= index_max; ++i) {
01022 array->SetValue(i, values[i - index_min]);
01023 }
01024 *callback = NewPermanentCallback(array, &ArrayWithOffset<T>::Evaluate);
01025 }
01026
01027 #define VERIFY(expr) if (!(expr)) return NULL
01028 #define VERIFY_EQ(e1, e2) if ((e1) != (e2)) return NULL
01029
01030
01031
01032 IntExpr* BuildAbs(CPModelLoader* const builder,
01033 const CPIntegerExpressionProto& proto) {
01034 IntExpr* expr = NULL;
01035 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01036 proto,
01037 &expr));
01038 return builder->solver()->MakeAbs(expr);
01039 }
01040
01041
01042
01043 Constraint* BuildAllDifferent(CPModelLoader* const builder,
01044 const CPConstraintProto& proto) {
01045 std::vector<IntVar*> vars;
01046 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01047 int64 range = 0;
01048 VERIFY(builder->ScanArguments(ModelVisitor::kRangeArgument, proto, &range));
01049 return builder->solver()->MakeAllDifferent(vars, range);
01050 }
01051
01052
01053
01054 Constraint* BuildAllowedAssignments(CPModelLoader* const builder,
01055 const CPConstraintProto& proto) {
01056 std::vector<IntVar*> vars;
01057 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01058 IntTupleSet tuples(vars.size());
01059 VERIFY(builder->ScanArguments(ModelVisitor::kTuplesArgument,
01060 proto,
01061 &tuples));
01062 return builder->solver()->MakeAllowedAssignments(vars, tuples);
01063 }
01064
01065
01066
01067 Constraint* BuildBetween(CPModelLoader* const builder,
01068 const CPConstraintProto& proto) {
01069 int64 value_min = 0;
01070 VERIFY(builder->ScanArguments(ModelVisitor::kMinArgument, proto, &value_min));
01071 int64 value_max = 0;
01072 VERIFY(builder->ScanArguments(ModelVisitor::kMaxArgument, proto, &value_max));
01073 IntExpr* expr = NULL;
01074 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01075 proto,
01076 &expr));
01077 return builder->solver()->MakeBetweenCt(expr->Var(), value_min, value_max);
01078 }
01079
01080
01081 IntExpr* BuildConvexPiecewise(CPModelLoader* const builder,
01082 const CPIntegerExpressionProto& proto) {
01083 IntExpr* expr = NULL;
01084 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01085 proto,
01086 &expr));
01087 int64 early_cost = 0;
01088 VERIFY(builder->ScanArguments(ModelVisitor::kEarlyCostArgument,
01089 proto,
01090 &early_cost));
01091 int64 early_date = 0;
01092 VERIFY(builder->ScanArguments(ModelVisitor::kEarlyDateArgument,
01093 proto,
01094 &early_date));
01095 int64 late_cost = 0;
01096 VERIFY(builder->ScanArguments(ModelVisitor::kLateCostArgument,
01097 proto,
01098 &late_cost));
01099 int64 late_date = 0;
01100 VERIFY(builder->ScanArguments(ModelVisitor::kLateDateArgument,
01101 proto,
01102 &late_date));
01103 return builder->solver()->MakeConvexPiecewiseExpr(expr->Var(),
01104 early_cost,
01105 early_date,
01106 late_date,
01107 late_cost);
01108 }
01109
01110
01111
01112 Constraint* BuildCountEqual(CPModelLoader* const builder,
01113 const CPConstraintProto& proto) {
01114 std::vector<IntVar*> vars;
01115 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01116 int64 value = 0;
01117 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01118 int64 count = 0;
01119 if (builder->ScanArguments(ModelVisitor::kCountArgument, proto, &value)) {
01120 return builder->solver()->MakeCount(vars, value, count);
01121 } else {
01122 IntExpr* count_expr = NULL;
01123 VERIFY(builder->ScanArguments(ModelVisitor::kCountArgument,
01124 proto,
01125 &count_expr));
01126 return builder->solver()->MakeCount(vars, value, count_expr->Var());
01127 }
01128 }
01129
01130
01131
01132 Constraint* BuildCumulative(CPModelLoader* const builder,
01133 const CPConstraintProto& proto) {
01134 std::vector<IntervalVar*> vars;
01135 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalsArgument,
01136 proto,
01137 &vars));
01138 std::vector<int64> demands;
01139 VERIFY(builder->ScanArguments(ModelVisitor::kDemandsArgument,
01140 proto,
01141 &demands));
01142 int64 capacity;
01143 VERIFY(builder->ScanArguments(ModelVisitor::kCapacityArgument,
01144 proto,
01145 &capacity));
01146 string name;
01147 if (proto.has_name()) {
01148 name = proto.name();
01149 }
01150 return builder->solver()->MakeCumulative(vars, demands, capacity, name);
01151 }
01152
01153
01154
01155 Constraint* BuildDeviation(CPModelLoader* const builder,
01156 const CPConstraintProto& proto) {
01157 std::vector<IntVar*> vars;
01158 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01159 IntExpr* target = NULL;
01160 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01161 int64 value = 0;
01162 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01163 return builder->solver()->MakeDeviation(vars, target->Var(), value);
01164 }
01165
01166
01167
01168 IntExpr* BuildDifference(CPModelLoader* const builder,
01169 const CPIntegerExpressionProto& proto) {
01170 IntExpr* left = NULL;
01171 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01172 IntExpr* right = NULL;
01173 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01174 return builder->solver()->MakeDifference(left, right);
01175 }
01176 IntExpr* expr = NULL;
01177 VERIFY(builder->ScanArguments(
01178 ModelVisitor::kExpressionArgument, proto, &expr));
01179 int64 value = 0;
01180 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01181 return builder->solver()->MakeDifference(value, expr);
01182 }
01183
01184
01185
01186 Constraint* BuildDisjunctive(CPModelLoader* const builder,
01187 const CPConstraintProto& proto) {
01188 std::vector<IntervalVar*> vars;
01189 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalsArgument,
01190 proto,
01191 &vars));
01192 return builder->solver()->MakeDisjunctiveConstraint(vars);
01193 }
01194
01195
01196
01197 Constraint* BuildDistribute(CPModelLoader* const builder,
01198 const CPConstraintProto& proto) {
01199 std::vector<IntVar*> vars;
01200 if (builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars)) {
01201 std::vector<IntVar*> cards;
01202 if (builder->ScanArguments(ModelVisitor::kCardsArgument, proto, &cards)) {
01203 std::vector<int64> values;
01204 if (builder->ScanArguments(ModelVisitor::kValuesArgument,
01205 proto,
01206 &values)) {
01207 return builder->solver()->MakeDistribute(vars, values, cards);
01208 } else {
01209 return builder->solver()->MakeDistribute(vars, cards);
01210 }
01211 } else {
01212 int64 card_min = 0;
01213 VERIFY(builder->ScanArguments(ModelVisitor::kMinArgument,
01214 proto,
01215 &card_min));
01216 int64 card_max = 0;
01217 VERIFY(builder->ScanArguments(ModelVisitor::kMaxArgument,
01218 proto,
01219 &card_max));
01220 int64 card_size = 0;
01221 VERIFY(builder->ScanArguments(ModelVisitor::kSizeArgument,
01222 proto,
01223 &card_size));
01224 return builder->solver()->MakeDistribute(vars,
01225 card_min,
01226 card_max,
01227 card_size);
01228 }
01229 } else {
01230 std::vector<IntVar*> cards;
01231 VERIFY(builder->ScanArguments(ModelVisitor::kCardsArgument, proto, &cards));
01232 return builder->solver()->MakeDistribute(vars, cards);
01233 }
01234 }
01235
01236
01237
01238 IntExpr* BuildDivide(CPModelLoader* const builder,
01239 const CPIntegerExpressionProto& proto) {
01240 IntExpr* expr = NULL;
01241 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01242 proto,
01243 &expr));
01244 int64 value = 0;
01245 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01246 return builder->solver()->MakeDiv(expr, value);
01247 }
01248
01249
01250
01251 IntExpr* BuildDurationExpr(CPModelLoader* const builder,
01252 const CPIntegerExpressionProto& proto) {
01253 IntervalVar* var = NULL;
01254 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalArgument, proto, &var));
01255 return var->DurationExpr();
01256 }
01257
01258
01259
01260 IntExpr* BuildElement(CPModelLoader* const builder,
01261 const CPIntegerExpressionProto& proto) {
01262 IntExpr* index = NULL;
01263 VERIFY(builder->ScanArguments(ModelVisitor::kIndexArgument, proto, &index));
01264 std::vector<int64> values;
01265 if (proto.extensions_size() > 0) {
01266 VERIFY_EQ(1, proto.extensions_size());
01267 Solver::IndexEvaluator1 * callback = NULL;
01268 const int extension_tag_index =
01269 builder->TagIndex(ModelVisitor::kInt64ToInt64Extension);
01270 MakeCallbackFromProto(builder,
01271 proto.extensions(0),
01272 extension_tag_index,
01273 &callback);
01274 return builder->solver()->MakeElement(callback, index->Var());
01275 }
01276 if (builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values)) {
01277 return builder->solver()->MakeElement(values, index->Var());
01278 }
01279 std::vector<IntVar*> vars;
01280 if (builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars)) {
01281 return builder->solver()->MakeElement(vars, index->Var());
01282 }
01283 return NULL;
01284 }
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 IntExpr* BuildEndExpr(CPModelLoader* const builder,
01322 const CPIntegerExpressionProto& proto) {
01323 IntervalVar* var = NULL;
01324 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalArgument, proto, &var));
01325 return var->EndExpr();
01326 }
01327
01328
01329
01330 Constraint* BuildEquality(CPModelLoader* const builder,
01331 const CPConstraintProto& proto) {
01332 IntExpr* left = NULL;
01333 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01334 IntExpr* right = NULL;
01335 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01336 return builder->solver()->MakeEquality(left->Var(), right->Var());
01337 }
01338 IntExpr* expr = NULL;
01339 if (builder->ScanArguments(ModelVisitor::kExpressionArgument, proto, &expr)) {
01340 int64 value = 0;
01341 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01342 return builder->solver()->MakeEquality(expr->Var(), value);
01343 }
01344 return NULL;
01345 }
01346
01347
01348
01349 Constraint* BuildFalseConstraint(CPModelLoader* const builder,
01350 const CPConstraintProto& proto) {
01351 return builder->solver()->MakeFalseConstraint();
01352 }
01353
01354
01355
01356 Constraint* BuildGreater(CPModelLoader* const builder,
01357 const CPConstraintProto& proto) {
01358 IntExpr* left = NULL;
01359 VERIFY(builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left));
01360 IntExpr* right = NULL;
01361 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01362 return builder->solver()->MakeGreater(left->Var(), right->Var());
01363 }
01364
01365
01366
01367 Constraint* BuildGreaterOrEqual(CPModelLoader* const builder,
01368 const CPConstraintProto& proto) {
01369 IntExpr* left = NULL;
01370 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01371 IntExpr* right = NULL;
01372 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01373 return builder->solver()->MakeGreaterOrEqual(left->Var(), right->Var());
01374 }
01375 IntExpr* expr = NULL;
01376 if (builder->ScanArguments(ModelVisitor::kExpressionArgument, proto, &expr)) {
01377 int64 value = 0;
01378 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01379 return builder->solver()->MakeGreaterOrEqual(expr->Var(), value);
01380 }
01381 return NULL;
01382 }
01383
01384
01385
01386 IntExpr* BuildIntegerVariable(CPModelLoader* const builder,
01387 const CPIntegerExpressionProto& proto) {
01388 IntExpr* sub_expression = NULL;
01389 if (builder->ScanArguments(ModelVisitor::kExpressionArgument,
01390 proto,
01391 &sub_expression)) {
01392 IntVar* const result = sub_expression->Var();
01393 if (proto.has_name()) {
01394 result->set_name(proto.name());
01395 }
01396 return result;
01397 }
01398 IntExpr* sub_var = NULL;
01399 if (builder->ScanArguments(ModelVisitor::kVariableArgument,
01400 proto,
01401 &sub_var)) {
01402 int64 value;
01403 IntVar* result = NULL;
01404 if (builder->ScanArguments(ModelVisitor::kSumOperation,
01405 proto,
01406 &value)) {
01407 result = builder->solver()->MakeSum(sub_var->Var(), value)->Var();
01408 } else if (builder->ScanArguments(ModelVisitor::kDifferenceOperation,
01409 proto,
01410 &value)) {
01411 result = builder->solver()->MakeDifference(value, sub_var->Var())->Var();
01412 } else if (builder->ScanArguments(ModelVisitor::kProductOperation,
01413 proto,
01414 &value)) {
01415 result = builder->solver()->MakeProd(sub_var->Var(), value)->Var();
01416 }
01417 if (proto.has_name()) {
01418 result->set_name(proto.name());
01419 }
01420 return result;
01421 }
01422 int64 var_min = 0;
01423 if (builder->ScanArguments(ModelVisitor::kMinArgument, proto, &var_min)) {
01424 int64 var_max = 0;
01425 VERIFY(builder->ScanArguments(ModelVisitor::kMaxArgument, proto, &var_max));
01426 IntVar* const result = builder->solver()->MakeIntVar(var_min, var_max);
01427 if (proto.has_name()) {
01428 result->set_name(proto.name());
01429 }
01430 return result;
01431 }
01432 std::vector<int64> values;
01433 if (builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values)) {
01434 IntVar* const result = builder->solver()->MakeIntVar(values);
01435 if (proto.has_name()) {
01436 result->set_name(proto.name());
01437 }
01438 return result;
01439 }
01440 return NULL;
01441 }
01442
01443
01444
01445 Constraint* BuildIntervalBinaryRelation(CPModelLoader* const builder,
01446 const CPConstraintProto& proto) {
01447 IntervalVar* left = NULL;
01448 VERIFY(builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left));
01449 IntervalVar* right = NULL;
01450 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01451 int64 relation = 0;
01452 VERIFY(builder->ScanArguments(ModelVisitor::kRelationArgument,
01453 proto,
01454 &relation));
01455 Solver::BinaryIntervalRelation rel =
01456 static_cast<Solver::BinaryIntervalRelation>(relation);
01457 return builder->solver()->MakeIntervalVarRelation(left, rel, right);
01458 }
01459
01460
01461
01462 Constraint* BuildIntervalDisjunction(CPModelLoader* const builder,
01463 const CPConstraintProto& proto) {
01464 IntervalVar* left = NULL;
01465 VERIFY(builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left));
01466 IntervalVar* right = NULL;
01467 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01468 IntExpr* target = NULL;
01469 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01470 return builder->solver()->MakeTemporalDisjunction(left, right, target->Var());
01471 }
01472
01473
01474
01475 Constraint* BuildIntervalUnaryRelation(CPModelLoader* const builder,
01476 const CPConstraintProto& proto) {
01477 IntervalVar* interval = NULL;
01478 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalArgument,
01479 proto,
01480 &interval));
01481 int64 date = 0;
01482 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &date));
01483 int64 relation = 0;
01484 VERIFY(builder->ScanArguments(ModelVisitor::kRelationArgument,
01485 proto,
01486 &relation));
01487 Solver::UnaryIntervalRelation rel =
01488 static_cast<Solver::UnaryIntervalRelation>(relation);
01489 return builder->solver()->MakeIntervalVarRelation(interval, rel, date);
01490 }
01491
01492
01493
01494 IntervalVar* BuildIntervalVariable(CPModelLoader* const builder,
01495 const CPIntervalVariableProto& proto) {
01496 Solver* const solver = builder->solver();
01497 int64 start_min = 0;
01498 if (builder->ScanArguments(ModelVisitor::kStartMinArgument,
01499 proto,
01500 &start_min)) {
01501 int64 start_max = 0;
01502 VERIFY(builder->ScanArguments(ModelVisitor::kStartMaxArgument,
01503 proto,
01504 &start_max));
01505 int64 end_min = 0;
01506 VERIFY(builder->ScanArguments(ModelVisitor::kEndMinArgument,
01507 proto,
01508 &end_min));
01509 int64 end_max = 0;
01510 VERIFY(builder->ScanArguments(ModelVisitor::kEndMaxArgument,
01511 proto,
01512 &end_max));
01513 int64 duration_min = 0;
01514 VERIFY(builder->ScanArguments(ModelVisitor::kDurationMinArgument,
01515 proto,
01516 &duration_min));
01517 int64 duration_max = 0;
01518 VERIFY(builder->ScanArguments(ModelVisitor::kDurationMaxArgument,
01519 proto,
01520 &duration_max));
01521 int64 optional = 0;
01522 VERIFY(builder->ScanArguments(ModelVisitor::kOptionalArgument,
01523 proto,
01524 &optional));
01525 VERIFY_EQ(duration_max, duration_min);
01526 VERIFY_EQ(end_max - duration_max, start_max);
01527 VERIFY_EQ(end_min - duration_min, start_min);
01528 const string name = proto.name();
01529 if (start_min == start_max) {
01530 return solver->MakeFixedInterval(start_min, duration_min, name);
01531 } else {
01532 return solver->MakeFixedDurationIntervalVar(start_min,
01533 start_max,
01534 duration_min,
01535 optional,
01536 name);
01537 }
01538 } else {
01539 VERIFY_EQ(1, proto.arguments_size());
01540 const CPArgumentProto& sub_proto = proto.arguments(0);
01541 IntervalVar* const derived =
01542 builder->IntervalVariable(sub_proto.interval_index());
01543 const int operation_index = sub_proto.argument_index();
01544 DCHECK_NE(-1, operation_index);
01545 if (operation_index == builder->TagIndex(ModelVisitor::kMirrorOperation)) {
01546 return solver->MakeMirrorInterval(derived);
01547 } else if (operation_index ==
01548 builder->TagIndex(ModelVisitor::kRelaxedMaxOperation)) {
01549 solver->MakeIntervalRelaxedMax(derived);
01550 } else if (operation_index ==
01551 builder->TagIndex(ModelVisitor::kRelaxedMinOperation)) {
01552 solver->MakeIntervalRelaxedMin(derived);
01553 }
01554 }
01555 return NULL;
01556 }
01557
01558
01559
01560 Constraint* BuildIsBetween(CPModelLoader* const builder,
01561 const CPConstraintProto& proto) {
01562 int64 value_min = 0;
01563 VERIFY(builder->ScanArguments(ModelVisitor::kMinArgument, proto, &value_min));
01564 int64 value_max = 0;
01565 VERIFY(builder->ScanArguments(ModelVisitor::kMaxArgument, proto, &value_max));
01566 IntExpr* expr = NULL;
01567 VERIFY(builder->ScanArguments(
01568 ModelVisitor::kExpressionArgument, proto, &expr));
01569 IntExpr* target = NULL;
01570 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01571 return builder->solver()->MakeIsBetweenCt(expr->Var(),
01572 value_min,
01573 value_max,
01574 target->Var());
01575 }
01576
01577
01578
01579 Constraint* BuildIsDifferent(CPModelLoader* const builder,
01580 const CPConstraintProto& proto) {
01581 int64 value = 0;
01582 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01583 IntExpr* expr = NULL;
01584 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01585 proto,
01586 &expr));
01587 IntExpr* target = NULL;
01588 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01589 return builder->solver()->MakeIsDifferentCstCt(expr->Var(),
01590 value,
01591 target->Var());
01592 }
01593
01594
01595
01596 Constraint* BuildIsEqual(CPModelLoader* const builder,
01597 const CPConstraintProto& proto) {
01598 int64 value = 0;
01599 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01600 IntExpr* expr = NULL;
01601 VERIFY(builder->ScanArguments(
01602 ModelVisitor::kExpressionArgument, proto, &expr));
01603 IntExpr* target = NULL;
01604 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01605 return builder->solver()->MakeIsEqualCstCt(expr->Var(),
01606 value,
01607 target->Var());
01608 }
01609
01610
01611
01612 Constraint* BuildIsGreaterOrEqual(CPModelLoader* const builder,
01613 const CPConstraintProto& proto) {
01614 int64 value = 0;
01615 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01616 IntExpr* expr = NULL;
01617 VERIFY(builder->ScanArguments(
01618 ModelVisitor::kExpressionArgument, proto, &expr));
01619 IntExpr* target = NULL;
01620 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01621 return builder->solver()->MakeIsGreaterOrEqualCstCt(expr->Var(),
01622 value,
01623 target->Var());
01624 }
01625
01626
01627
01628 Constraint* BuildIsLessOrEqual(CPModelLoader* const builder,
01629 const CPConstraintProto& proto) {
01630 int64 value = 0;
01631 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01632 IntExpr* expr = NULL;
01633 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01634 proto,
01635 &expr));
01636 IntExpr* target = NULL;
01637 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01638 return builder->solver()->MakeIsLessOrEqualCstCt(expr->Var(),
01639 value,
01640 target->Var());
01641 }
01642
01643
01644
01645 Constraint* BuildIsMember(CPModelLoader* const builder,
01646 const CPConstraintProto& proto) {
01647 std::vector<int64> values;
01648 VERIFY(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values));
01649 IntExpr* expr = NULL;
01650 VERIFY(builder->ScanArguments(
01651 ModelVisitor::kExpressionArgument, proto, &expr));
01652 IntExpr* target = NULL;
01653 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01654 return builder->solver()->MakeIsMemberCt(expr->Var(), values, target->Var());
01655 }
01656
01657
01658
01659 Constraint* BuildLess(CPModelLoader* const builder,
01660 const CPConstraintProto& proto) {
01661 IntExpr* left = NULL;
01662 VERIFY(builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left));
01663 IntExpr* right = NULL;
01664 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01665 return builder->solver()->MakeLess(left->Var(), right->Var());
01666 }
01667
01668
01669
01670 Constraint* BuildLessOrEqual(CPModelLoader* const builder,
01671 const CPConstraintProto& proto) {
01672 IntExpr* left = NULL;
01673 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01674 IntExpr* right = NULL;
01675 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01676 return builder->solver()->MakeLessOrEqual(left->Var(), right->Var());
01677 }
01678 IntExpr* expr = NULL;
01679 if (builder->ScanArguments(ModelVisitor::kExpressionArgument, proto, &expr)) {
01680 int64 value = 0;
01681 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01682 return builder->solver()->MakeLessOrEqual(expr->Var(), value);
01683 }
01684 return NULL;
01685 }
01686
01687
01688
01689 Constraint* BuildMapDomain(CPModelLoader* const builder,
01690 const CPConstraintProto& proto) {
01691 std::vector<IntVar*> vars;
01692 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01693 IntExpr* target = NULL;
01694 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01695 return builder->solver()->MakeMapDomain(target->Var(), vars);
01696 }
01697
01698
01699
01700 IntExpr* BuildMax(CPModelLoader* const builder,
01701 const CPIntegerExpressionProto& proto) {
01702 IntExpr* left = NULL;
01703 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01704 IntExpr* right = NULL;
01705 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01706 return builder->solver()->MakeMax(left, right);
01707 }
01708 IntExpr* expr = NULL;
01709 if (builder->ScanArguments(
01710 ModelVisitor::kExpressionArgument, proto, &expr)) {
01711 int64 value = 0;
01712 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01713 return builder->solver()->MakeMax(expr, value);
01714 }
01715 std::vector<IntVar*> vars;
01716 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01717 return builder->solver()->MakeMax(vars);
01718 }
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 Constraint* BuildMember(CPModelLoader* const builder,
01741 const CPConstraintProto& proto) {
01742 std::vector<int64> values;
01743 VERIFY(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values));
01744 IntExpr* expr = NULL;
01745 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01746 proto,
01747 &expr));
01748 return builder->solver()->MakeMemberCt(expr->Var(), values);
01749 }
01750
01751
01752
01753 IntExpr* BuildMin(CPModelLoader* const builder,
01754 const CPIntegerExpressionProto& proto) {
01755 IntExpr* left = NULL;
01756 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01757 IntExpr* right = NULL;
01758 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01759 return builder->solver()->MakeMin(left, right);
01760 }
01761 IntExpr* expr = NULL;
01762 if (builder->ScanArguments(ModelVisitor::kExpressionArgument, proto, &expr)) {
01763 int64 value = 0;
01764 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01765 return builder->solver()->MakeMin(expr, value);
01766 }
01767 std::vector<IntVar*> vars;
01768 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01769 return builder->solver()->MakeMin(vars);
01770 }
01771
01772
01773
01774
01775
01776
01777
01778 Constraint* BuildNoCycle(CPModelLoader* const builder,
01779 const CPConstraintProto& proto) {
01780 std::vector<IntVar*> nexts;
01781 VERIFY(builder->ScanArguments(ModelVisitor::kNextsArgument, proto, &nexts));
01782 std::vector<IntVar*> active;
01783 VERIFY(builder->ScanArguments(ModelVisitor::kActiveArgument, proto, &active));
01784 int64 assume_paths = 0;
01785 VERIFY(builder->ScanArguments(ModelVisitor::kAssumePathsArgument,
01786 proto,
01787 &assume_paths));
01788 ResultCallback1<bool, int64>* sink_handler = NULL;
01789 if (proto.extensions_size() > 0) {
01790 VERIFY_EQ(1, proto.extensions_size());
01791 const int tag_index =
01792 builder->TagIndex(ModelVisitor::kInt64ToBoolExtension);
01793 MakeCallbackFromProto(builder,
01794 proto.extensions(0),
01795 tag_index,
01796 &sink_handler);
01797 }
01798 return builder->solver()->MakeNoCycle(nexts, active, NULL, assume_paths);
01799 }
01800
01801
01802
01803 Constraint* BuildNonEqual(CPModelLoader* const builder,
01804 const CPConstraintProto& proto) {
01805 IntExpr* left = NULL;
01806 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01807 IntExpr* right = NULL;
01808 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01809 return builder->solver()->MakeNonEquality(left->Var(), right->Var());
01810 }
01811 IntExpr* expr = NULL;
01812 if (builder->ScanArguments(ModelVisitor::kExpressionArgument, proto, &expr)) {
01813 int64 value = 0;
01814 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01815 return builder->solver()->MakeNonEquality(expr->Var(), value);
01816 }
01817 return NULL;
01818 }
01819
01820
01821
01822 IntExpr* BuildOpposite(CPModelLoader* const builder,
01823 const CPIntegerExpressionProto& proto) {
01824 IntExpr* expr = NULL;
01825 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01826 proto,
01827 &expr));
01828 return builder->solver()->MakeOpposite(expr);
01829 }
01830
01831
01832
01833 bool AddUsageLessConstantDimension(Pack* const pack,
01834 CPModelLoader* const builder,
01835 const CPExtensionProto& proto) {
01836 std::vector<int64> weights;
01837 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
01838 proto,
01839 &weights));
01840 std::vector<int64> upper;
01841 VERIFY(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &upper));
01842 pack->AddWeightedSumLessOrEqualConstantDimension(weights, upper);
01843 return true;
01844 }
01845
01846 bool AddCountAssignedItemsDimension(Pack* const pack,
01847 CPModelLoader* const builder,
01848 const CPExtensionProto& proto) {
01849 IntExpr* target = NULL;
01850 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01851 pack->AddCountAssignedItemsDimension(target->Var());
01852 return true;
01853 }
01854
01855 bool AddCountUsedBinDimension(Pack* const pack,
01856 CPModelLoader* const builder,
01857 const CPExtensionProto& proto) {
01858 IntExpr* target = NULL;
01859 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01860 pack->AddCountUsedBinDimension(target->Var());
01861 return true;
01862 }
01863
01864 bool AddUsageEqualVariableDimension(Pack* const pack,
01865 CPModelLoader* const builder,
01866 const CPExtensionProto& proto) {
01867 std::vector<int64> weights;
01868 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
01869 proto,
01870 &weights));
01871 std::vector<IntVar*> loads;
01872 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &loads));
01873 pack->AddWeightedSumEqualVarDimension(weights, loads);
01874 return true;
01875 }
01876
01877 bool AddVariableUsageLessConstantDimension(Pack* const pack,
01878 CPModelLoader* const builder,
01879 const CPExtensionProto& proto) {
01880 std::vector<int64> uppers;
01881 VERIFY(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &uppers));
01882 std::vector<IntVar*> usages;
01883 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &usages));
01884 pack->AddSumVariableWeightsLessOrEqualConstantDimension(usages, uppers);
01885 return true;
01886 }
01887
01888 bool AddWeightedSumOfAssignedDimension(Pack* const pack,
01889 CPModelLoader* const builder,
01890 const CPExtensionProto& proto) {
01891 std::vector<int64> weights;
01892 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
01893 proto,
01894 &weights));
01895 IntExpr* target = NULL;
01896 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
01897 pack->AddWeightedSumOfAssignedDimension(weights, target->Var());
01898 return true;
01899 }
01900
01901 #define IS_TYPE(index, builder, tag) \
01902 index == builder->TagIndex(ModelVisitor::tag)
01903
01904 Constraint* BuildPack(CPModelLoader* const builder,
01905 const CPConstraintProto& proto) {
01906 std::vector<IntVar*> vars;
01907 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01908 int64 bins = 0;
01909 VERIFY(builder->ScanArguments(ModelVisitor::kSizeArgument, proto, &bins));
01910 Pack* const pack = builder->solver()->MakePack(vars, bins);
01911
01912 for (int i = 0; i < proto.extensions_size(); ++i) {
01913 const CPExtensionProto& dimension_proto = proto.extensions(i);
01914 const int type_index = dimension_proto.type_index();
01915 if (IS_TYPE(type_index, builder, kUsageLessConstantExtension)) {
01916 VERIFY(AddUsageLessConstantDimension(pack, builder, dimension_proto));
01917 } else if (IS_TYPE(type_index, builder, kCountAssignedItemsExtension)) {
01918 VERIFY(AddCountAssignedItemsDimension(pack, builder, dimension_proto));
01919 } else if (IS_TYPE(type_index, builder, kCountUsedBinsExtension)) {
01920 VERIFY(AddCountUsedBinDimension(pack, builder, dimension_proto));
01921 } else if (IS_TYPE(type_index, builder, kUsageEqualVariableExtension)) {
01922 VERIFY(AddUsageEqualVariableDimension(pack, builder, dimension_proto));
01923 } else if (IS_TYPE(type_index,
01924 builder,
01925 kVariableUsageLessConstantExtension)) {
01926 VERIFY(AddVariableUsageLessConstantDimension(pack,
01927 builder,
01928 dimension_proto));
01929 } else if (IS_TYPE(type_index,
01930 builder,
01931 kWeightedSumOfAssignedEqualVariableExtension)) {
01932 VERIFY(AddWeightedSumOfAssignedDimension(pack, builder, dimension_proto));
01933 } else {
01934 LOG(ERROR) << "Unrecognized extension " << dimension_proto.DebugString();
01935 return NULL;
01936 }
01937 }
01938 return pack;
01939 }
01940 #undef IS_TYPE
01941
01942
01943
01944 Constraint* BuildPathCumul(CPModelLoader* const builder,
01945 const CPConstraintProto& proto) {
01946 std::vector<IntVar*> nexts;
01947 VERIFY(builder->ScanArguments(ModelVisitor::kNextsArgument, proto, &nexts));
01948 std::vector<IntVar*> active;
01949 VERIFY(builder->ScanArguments(ModelVisitor::kActiveArgument, proto, &active));
01950 std::vector<IntVar*> cumuls;
01951 VERIFY(builder->ScanArguments(ModelVisitor::kCumulsArgument, proto, &cumuls));
01952 std::vector<IntVar*> transits;
01953 VERIFY(builder->ScanArguments(ModelVisitor::kTransitsArgument,
01954 proto,
01955 &transits));
01956 return builder->solver()->MakePathCumul(nexts, active, cumuls, transits);
01957 }
01958
01959
01960
01961 IntExpr* BuildPerformedExpr(CPModelLoader* const builder,
01962 const CPIntegerExpressionProto& proto) {
01963 IntervalVar* var = NULL;
01964 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalArgument, proto, &var));
01965 return var->PerformedExpr();
01966 }
01967
01968
01969
01970 IntExpr* BuildProduct(CPModelLoader* const builder,
01971 const CPIntegerExpressionProto& proto) {
01972 IntExpr* left = NULL;
01973 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
01974 IntExpr* right = NULL;
01975 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
01976 return builder->solver()->MakeProd(left, right);
01977 }
01978 IntExpr* expr = NULL;
01979 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
01980 proto,
01981 &expr));
01982 int64 value = 0;
01983 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
01984 return builder->solver()->MakeProd(expr, value);
01985 }
01986
01987
01988
01989 IntExpr* BuildScalProd(CPModelLoader* const builder,
01990 const CPIntegerExpressionProto& proto) {
01991 std::vector<IntVar*> vars;
01992 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
01993 std::vector<int64> values;
01994 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
01995 proto,
01996 &values));
01997 return builder->solver()->MakeScalProd(vars, values);
01998 }
01999
02000
02001
02002 Constraint* BuildScalProdEqual(CPModelLoader* const builder,
02003 const CPConstraintProto& proto) {
02004 std::vector<IntVar*> vars;
02005 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02006 std::vector<int64> values;
02007 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
02008 proto,
02009 &values));
02010 int64 value = 0;
02011 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02012 return builder->solver()->MakeScalProdEquality(vars, values, value);
02013 }
02014
02015
02016
02017 Constraint* BuildScalProdGreaterOrEqual(CPModelLoader* const builder,
02018 const CPConstraintProto& proto) {
02019 std::vector<IntVar*> vars;
02020 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02021 std::vector<int64> values;
02022 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
02023 proto,
02024 &values));
02025 int64 value = 0;
02026 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02027 return builder->solver()->MakeScalProdGreaterOrEqual(vars, values, value);
02028 }
02029
02030
02031
02032 Constraint* BuildScalProdLessOrEqual(CPModelLoader* const builder,
02033 const CPConstraintProto& proto) {
02034 std::vector<IntVar*> vars;
02035 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02036 std::vector<int64> values;
02037 VERIFY(builder->ScanArguments(ModelVisitor::kCoefficientsArgument,
02038 proto,
02039 &values));
02040 int64 value = 0;
02041 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02042 return builder->solver()->MakeScalProdLessOrEqual(vars, values, value);
02043 }
02044
02045
02046
02047 IntExpr* BuildSemiContinuous(CPModelLoader* const builder,
02048 const CPIntegerExpressionProto& proto) {
02049 IntExpr* expr = NULL;
02050 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
02051 proto,
02052 &expr));
02053 int64 fixed_charge = 0;
02054 VERIFY(builder->ScanArguments(ModelVisitor::kFixedChargeArgument,
02055 proto,
02056 &fixed_charge));
02057 int64 step = 0;
02058 VERIFY(builder->ScanArguments(ModelVisitor::kStepArgument, proto, &step));
02059 return builder->solver()->MakeSemiContinuousExpr(expr, fixed_charge, step);
02060 }
02061
02062
02063
02064 SequenceVar* BuildSequenceVariable(CPModelLoader* const builder,
02065 const CPSequenceVariableProto& proto) {
02066 std::vector<IntervalVar*> vars;
02067 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalsArgument,
02068 proto,
02069 &vars));
02070 return builder->solver()->MakeSequenceVar(vars, proto.name());
02071 }
02072
02073
02074
02075 IntExpr* BuildSquare(CPModelLoader* const builder,
02076 const CPIntegerExpressionProto& proto) {
02077 IntExpr* expr = NULL;
02078 VERIFY(builder->ScanArguments(ModelVisitor::kExpressionArgument,
02079 proto,
02080 &expr));
02081 return builder->solver()->MakeSquare(expr);
02082 }
02083
02084
02085
02086 IntExpr* BuildStartExpr(CPModelLoader* const builder,
02087 const CPIntegerExpressionProto& proto) {
02088 IntervalVar* var = NULL;
02089 VERIFY(builder->ScanArguments(ModelVisitor::kIntervalArgument, proto, &var));
02090 return var->StartExpr();
02091 }
02092
02093
02094
02095 IntExpr* BuildSum(CPModelLoader* const builder,
02096 const CPIntegerExpressionProto& proto) {
02097 IntExpr* left = NULL;
02098 if (builder->ScanArguments(ModelVisitor::kLeftArgument, proto, &left)) {
02099 IntExpr* right = NULL;
02100 VERIFY(builder->ScanArguments(ModelVisitor::kRightArgument, proto, &right));
02101 return builder->solver()->MakeSum(left, right);
02102 }
02103 IntExpr* expr = NULL;
02104 if (builder->ScanArguments(
02105 ModelVisitor::kExpressionArgument, proto, &expr)) {
02106 int64 value = 0;
02107 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02108 return builder->solver()->MakeSum(expr, value);
02109 }
02110 std::vector<IntVar*> vars;
02111 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02112 return builder->solver()->MakeSum(vars);
02113 }
02114
02115
02116
02117 Constraint* BuildSumEqual(CPModelLoader* const builder,
02118 const CPConstraintProto& proto) {
02119 std::vector<IntVar*> vars;
02120 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02121 int64 value = 0;
02122 if (builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value)) {
02123 return builder->solver()->MakeSumEquality(vars, value);
02124 }
02125 IntExpr* target = NULL;
02126 VERIFY(builder->ScanArguments(ModelVisitor::kTargetArgument, proto, &target));
02127 return builder->solver()->MakeSumEquality(vars, target->Var());
02128 }
02129
02130
02131
02132 Constraint* BuildSumGreaterOrEqual(CPModelLoader* const builder,
02133 const CPConstraintProto& proto) {
02134 std::vector<IntVar*> vars;
02135 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02136 int64 value = 0;
02137 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02138 return builder->solver()->MakeSumGreaterOrEqual(vars, value);
02139 }
02140
02141
02142
02143 Constraint* BuildSumLessOrEqual(CPModelLoader* const builder,
02144 const CPConstraintProto& proto) {
02145 std::vector<IntVar*> vars;
02146 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02147 int64 value = 0;
02148 VERIFY(builder->ScanArguments(ModelVisitor::kValueArgument, proto, &value));
02149 return builder->solver()->MakeSumLessOrEqual(vars, value);
02150 }
02151
02152
02153
02154 Constraint* BuildTransition(CPModelLoader* const builder,
02155 const CPConstraintProto& proto) {
02156 std::vector<IntVar*> vars;
02157 VERIFY(builder->ScanArguments(ModelVisitor::kVarsArgument, proto, &vars));
02158 IntTupleSet tuples(3);
02159 VERIFY(builder->ScanArguments(ModelVisitor::kTuplesArgument,
02160 proto,
02161 &tuples));
02162 int64 initial_state = 0;
02163 VERIFY(builder->ScanArguments(ModelVisitor::kInitialState,
02164 proto,
02165 &initial_state));
02166 std::vector<int64> final_states;
02167 VERIFY(builder->ScanArguments(ModelVisitor::kFinalStatesArgument,
02168 proto,
02169 &final_states));
02170
02171
02172
02173 return builder->solver()->MakeTransitionConstraint(vars,
02174 tuples,
02175 initial_state,
02176 final_states);
02177 }
02178
02179
02180
02181 Constraint* BuildTrueConstraint(CPModelLoader* const builder,
02182 const CPConstraintProto& proto) {
02183 return builder->solver()->MakeTrueConstraint();
02184 }
02185
02186 #undef VERIFY
02187 #undef VERIFY_EQ
02188 }
02189
02190
02191
02192 bool CPModelLoader::BuildFromProto(const CPIntegerExpressionProto& proto) {
02193 const int index = proto.index();
02194 const int tag_index = proto.type_index();
02195 Solver::IntegerExpressionBuilder* const builder =
02196 solver_->GetIntegerExpressionBuilder(tags_.Element(tag_index));
02197 if (!builder) {
02198 return false;
02199 }
02200 IntExpr* const built = builder->Run(this, proto);
02201 if (!built) {
02202 return false;
02203 }
02204 expressions_.resize(std::max(static_cast<int>(expressions_.size()),
02205 index + 1));
02206 expressions_[index] = built;
02207 return true;
02208 }
02209
02210 Constraint* CPModelLoader::BuildFromProto(const CPConstraintProto& proto) {
02211 const int tag_index = proto.type_index();
02212 Solver::ConstraintBuilder* const builder =
02213 solver_->GetConstraintBuilder(tags_.Element(tag_index));
02214 if (!builder) {
02215 return NULL;
02216 }
02217 Constraint* const built = builder->Run(this, proto);
02218 return built;
02219 }
02220
02221 bool CPModelLoader::BuildFromProto(const CPIntervalVariableProto& proto) {
02222 const int index = proto.index();
02223 const int tag_index = proto.type_index();
02224 Solver::IntervalVariableBuilder* const builder =
02225 solver_->GetIntervalVariableBuilder(tags_.Element(tag_index));
02226 if (!builder) {
02227 return NULL;
02228 }
02229 IntervalVar* const built = builder->Run(this, proto);
02230 if (!built) {
02231 return false;
02232 }
02233 intervals_.resize(std::max(static_cast<int>(intervals_.size()), index + 1));
02234 intervals_[index] = built;
02235 return true;
02236 }
02237
02238 bool CPModelLoader::BuildFromProto(const CPSequenceVariableProto& proto) {
02239 const int index = proto.index();
02240 const int tag_index = proto.type_index();
02241 Solver::SequenceVariableBuilder* const builder =
02242 solver_->GetSequenceVariableBuilder(tags_.Element(tag_index));
02243 if (!builder) {
02244 return NULL;
02245 }
02246 SequenceVar* const built = builder->Run(this, proto);
02247 if (!built) {
02248 return false;
02249 }
02250 sequences_.resize(std::max(static_cast<int>(sequences_.size()), index + 1));
02251 sequences_[index] = built;
02252 return true;
02253 }
02254
02255 IntExpr* CPModelLoader::IntegerExpression(int index) const {
02256 CHECK_GE(index, 0);
02257 CHECK_LT(index, expressions_.size());
02258 CHECK_NOTNULL(expressions_[index]);
02259 return expressions_[index];
02260 }
02261
02262 IntervalVar* CPModelLoader::IntervalVariable(int index) const {
02263 CHECK_GE(index, 0);
02264 CHECK_LT(index, intervals_.size());
02265 CHECK_NOTNULL(intervals_[index]);
02266 return intervals_[index];
02267 }
02268
02269 bool CPModelLoader::ScanOneArgument(int type_index,
02270 const CPArgumentProto& arg_proto,
02271 int64* to_fill) {
02272 if (arg_proto.argument_index() == type_index &&
02273 arg_proto.has_integer_value()) {
02274 *to_fill = arg_proto.integer_value();
02275 return true;
02276 }
02277 return false;
02278 }
02279
02280 bool CPModelLoader::ScanOneArgument(int type_index,
02281 const CPArgumentProto& arg_proto,
02282 IntExpr** to_fill) {
02283 if (arg_proto.argument_index() == type_index &&
02284 arg_proto.has_integer_expression_index()) {
02285 const int expression_index = arg_proto.integer_expression_index();
02286 CHECK_NOTNULL(expressions_[expression_index]);
02287 *to_fill = expressions_[expression_index];
02288 return true;
02289 }
02290 return false;
02291 }
02292
02293 bool CPModelLoader::ScanOneArgument(int type_index,
02294 const CPArgumentProto& arg_proto,
02295 std::vector<int64>* to_fill) {
02296 if (arg_proto.argument_index() == type_index) {
02297 const int values_size = arg_proto.integer_array_size();
02298 for (int j = 0; j < values_size; ++j) {
02299 to_fill->push_back(arg_proto.integer_array(j));
02300 }
02301 return true;
02302 }
02303 return false;
02304 }
02305
02306 bool CPModelLoader::ScanOneArgument(int type_index,
02307 const CPArgumentProto& arg_proto,
02308 IntTupleSet* to_fill) {
02309 if (arg_proto.argument_index() == type_index &&
02310 arg_proto.has_integer_matrix()) {
02311 to_fill->Clear();
02312 const CPIntegerMatrixProto& matrix = arg_proto.integer_matrix();
02313 const int rows = matrix.rows();
02314 const int columns = matrix.columns();
02315 int counter = 0;
02316 for (int i = 0; i < rows; ++i) {
02317 std::vector<int64> tuple;
02318 for (int j = 0; j < columns; ++j) {
02319 const int64 value = matrix.values(counter++);
02320 tuple.push_back(value);
02321 }
02322 to_fill->Insert(tuple);
02323 }
02324 CHECK_EQ(matrix.values_size(), counter);
02325 return true;
02326 }
02327 return false;
02328 }
02329
02330 bool CPModelLoader::ScanOneArgument(int type_index,
02331 const CPArgumentProto& arg_proto,
02332 std::vector<IntVar*>* to_fill) {
02333 if (arg_proto.argument_index() == type_index) {
02334 const int vars_size = arg_proto.integer_expression_array_size();
02335 for (int j = 0; j < vars_size; ++j) {
02336 const int expression_index = arg_proto.integer_expression_array(j);
02337 CHECK_NOTNULL(expressions_[expression_index]);
02338 to_fill->push_back(expressions_[expression_index]->Var());
02339 }
02340 return true;
02341 }
02342 return false;
02343 }
02344
02345 bool CPModelLoader::ScanOneArgument(int type_index,
02346 const CPArgumentProto& arg_proto,
02347 IntervalVar** to_fill) {
02348 if (arg_proto.argument_index() == type_index &&
02349 arg_proto.has_interval_index()) {
02350 const int interval_index = arg_proto.interval_index();
02351 CHECK_NOTNULL(intervals_[interval_index]);
02352 *to_fill = intervals_[interval_index];
02353 return true;
02354 }
02355 return false;
02356 }
02357
02358 bool CPModelLoader::ScanOneArgument(int type_index,
02359 const CPArgumentProto& arg_proto,
02360 std::vector<IntervalVar*>* to_fill) {
02361 if (arg_proto.argument_index() == type_index) {
02362 const int vars_size = arg_proto.interval_array_size();
02363 for (int j = 0; j < vars_size; ++j) {
02364 const int interval_index = arg_proto.interval_array(j);
02365 CHECK_NOTNULL(intervals_[interval_index]);
02366 to_fill->push_back(intervals_[interval_index]);
02367 }
02368 return true;
02369 }
02370 return false;
02371 }
02372
02373 bool CPModelLoader::ScanOneArgument(int type_index,
02374 const CPArgumentProto& arg_proto,
02375 SequenceVar** to_fill) {
02376 if (arg_proto.argument_index() == type_index &&
02377 arg_proto.has_sequence_index()) {
02378 const int sequence_index = arg_proto.sequence_index();
02379 CHECK_NOTNULL(sequences_[sequence_index]);
02380 *to_fill = sequences_[sequence_index];
02381 return true;
02382 }
02383 return false;
02384 }
02385
02386 bool CPModelLoader::ScanOneArgument(int type_index,
02387 const CPArgumentProto& arg_proto,
02388 std::vector<SequenceVar*>* to_fill) {
02389 if (arg_proto.argument_index() == type_index) {
02390 const int vars_size = arg_proto.sequence_array_size();
02391 for (int j = 0; j < vars_size; ++j) {
02392 const int sequence_index = arg_proto.sequence_array(j);
02393 CHECK_NOTNULL(sequences_[sequence_index]);
02394 to_fill->push_back(sequences_[sequence_index]);
02395 }
02396 return true;
02397 }
02398 return false;
02399 }
02400
02401
02402
02403 void Solver::ExportModel(const std::vector<SearchMonitor*>& monitors,
02404 CPModelProto* const model_proto) const {
02405 CHECK_NOTNULL(model_proto);
02406 FirstPassVisitor first_pass;
02407 Accept(&first_pass);
02408 for (ConstIter<std::vector<SearchMonitor*> > it(monitors); !it.at_end(); ++it) {
02409 (*it)->Accept(&first_pass);
02410 }
02411 SecondPassVisitor second_pass(first_pass, model_proto);
02412 for (ConstIter<std::vector<SearchMonitor*> > it(monitors); !it.at_end(); ++it) {
02413 (*it)->Accept(&second_pass);
02414 }
02415 Accept(&second_pass);
02416 }
02417
02418 void Solver::ExportModel(CPModelProto* const model_proto) const {
02419 CHECK_NOTNULL(model_proto);
02420 FirstPassVisitor first_pass;
02421 Accept(&first_pass);
02422 SecondPassVisitor second_pass(first_pass, model_proto);
02423 Accept(&second_pass);
02424 }
02425
02426 bool Solver::LoadModel(const CPModelProto& model_proto) {
02427 return LoadModel(model_proto, NULL);
02428 }
02429
02430 bool Solver::LoadModel(const CPModelProto& model_proto,
02431 std::vector<SearchMonitor*>* monitors) {
02432 if (model_proto.version() > kModelVersion) {
02433 LOG(ERROR) << "Model protocol buffer version is greater than"
02434 << " the one compiled in the reader ("
02435 << model_proto.version() << " vs " << kModelVersion << ")";
02436 return false;
02437 }
02438 CPModelLoader builder(this);
02439 for (int i = 0; i < model_proto.tags_size(); ++i) {
02440 builder.AddTag(model_proto.tags(i));
02441 }
02442 for (int i = 0; i < model_proto.intervals_size(); ++i) {
02443 if (!builder.BuildFromProto(model_proto.intervals(i))) {
02444 LOG(ERROR) << "Interval variable proto "
02445 << model_proto.intervals(i).DebugString()
02446 << " was not parsed correctly";
02447 return false;
02448 }
02449 }
02450 for (int i = 0; i < model_proto.sequences_size(); ++i) {
02451 if (!builder.BuildFromProto(model_proto.sequences(i))) {
02452 LOG(ERROR) << "Sequence variable proto "
02453 << model_proto.sequences(i).DebugString()
02454 << " was not parsed correctly";
02455 return false;
02456 }
02457 }
02458 for (int i = 0; i < model_proto.expressions_size(); ++i) {
02459 if (!builder.BuildFromProto(model_proto.expressions(i))) {
02460 LOG(ERROR) << "Integer expression proto "
02461 << model_proto.expressions(i).DebugString()
02462 << " was not parsed correctly";
02463 return false;
02464 }
02465 }
02466 for (int i = 0; i < model_proto.constraints_size(); ++i) {
02467 Constraint* const constraint =
02468 builder.BuildFromProto(model_proto.constraints(i));
02469 if (constraint == NULL) {
02470 LOG(ERROR) << "Constraint proto "
02471 << model_proto.constraints(i).DebugString()
02472 << " was not parsed correctly";
02473 return false;
02474 }
02475 AddConstraint(constraint);
02476 }
02477 if (monitors != NULL) {
02478 if (model_proto.has_search_limit()) {
02479 monitors->push_back(MakeLimit(model_proto.search_limit()));
02480 }
02481 if (model_proto.has_objective()) {
02482 const CPObjectiveProto& objective_proto = model_proto.objective();
02483 IntVar* const objective_var =
02484 builder.IntegerExpression(objective_proto.objective_index())->Var();
02485 const bool maximize = objective_proto.maximize();
02486 const int64 step = objective_proto.step();
02487 OptimizeVar* const objective =
02488 MakeOptimize(maximize, objective_var, step);
02489 monitors->push_back(objective);
02490 }
02491 }
02492 return true;
02493 }
02494
02495 bool Solver::UpgradeModel(CPModelProto* const proto) {
02496 if (proto->version() == kModelVersion) {
02497 LOG(INFO) << "Model already up to date with version " << kModelVersion;
02498 }
02499 return true;
02500 }
02501
02502 void Solver::RegisterBuilder(const string& tag,
02503 ConstraintBuilder* const builder) {
02504 InsertOrDie(&constraint_builders_, tag, builder);
02505 }
02506
02507 void Solver::RegisterBuilder(const string& tag,
02508 IntegerExpressionBuilder* const builder) {
02509 InsertOrDie(&expression_builders_, tag, builder);
02510 }
02511
02512 void Solver::RegisterBuilder(const string& tag,
02513 IntervalVariableBuilder* const builder) {
02514 InsertOrDie(&interval_builders_, tag, builder);
02515 }
02516
02517 void Solver::RegisterBuilder(const string& tag,
02518 SequenceVariableBuilder* const builder) {
02519 InsertOrDie(&sequence_builders_, tag, builder);
02520 }
02521
02522 Solver::ConstraintBuilder*
02523 Solver::GetConstraintBuilder(const string& tag) const {
02524 return FindPtrOrNull(constraint_builders_, tag);
02525 }
02526
02527 Solver::IntegerExpressionBuilder*
02528 Solver::GetIntegerExpressionBuilder(const string& tag) const {
02529 return FindPtrOrNull(expression_builders_, tag);
02530 }
02531
02532 Solver::IntervalVariableBuilder*
02533 Solver::GetIntervalVariableBuilder(const string& tag) const {
02534 IntervalVariableBuilder* const builder =
02535 FindPtrOrNull(interval_builders_, tag);
02536 return builder;
02537 }
02538
02539 Solver::SequenceVariableBuilder*
02540 Solver::GetSequenceVariableBuilder(const string& tag) const {
02541 SequenceVariableBuilder* const builder =
02542 FindPtrOrNull(sequence_builders_, tag);
02543 return builder;
02544 }
02545
02546
02547
02548 #define REGISTER(tag, func) \
02549 RegisterBuilder(ModelVisitor::tag, NewPermanentCallback(&func))
02550
02551 void Solver::InitBuilders() {
02552 REGISTER(kAbs, BuildAbs);
02553 REGISTER(kAllDifferent, BuildAllDifferent);
02554 REGISTER(kAllowedAssignments, BuildAllowedAssignments);
02555 REGISTER(kBetween, BuildBetween);
02556 REGISTER(kConvexPiecewise, BuildConvexPiecewise);
02557 REGISTER(kCountEqual, BuildCountEqual);
02558 REGISTER(kCumulative, BuildCumulative);
02559 REGISTER(kDeviation, BuildDeviation);
02560 REGISTER(kDifference, BuildDifference);
02561 REGISTER(kDisjunctive, BuildDisjunctive);
02562 REGISTER(kDistribute, BuildDistribute);
02563 REGISTER(kDivide, BuildDivide);
02564 REGISTER(kDurationExpr, BuildDurationExpr);
02565 REGISTER(kElement, BuildElement);
02566
02567 REGISTER(kEndExpr, BuildEndExpr);
02568 REGISTER(kEquality, BuildEquality);
02569 REGISTER(kFalseConstraint, BuildFalseConstraint);
02570 REGISTER(kGreater, BuildGreater);
02571 REGISTER(kGreaterOrEqual, BuildGreaterOrEqual);
02572 REGISTER(kIntegerVariable, BuildIntegerVariable);
02573 REGISTER(kIntervalBinaryRelation, BuildIntervalBinaryRelation);
02574 REGISTER(kIntervalDisjunction, BuildIntervalDisjunction);
02575 REGISTER(kIntervalUnaryRelation, BuildIntervalUnaryRelation);
02576 REGISTER(kIntervalVariable, BuildIntervalVariable);
02577 REGISTER(kIsBetween, BuildIsBetween);
02578 REGISTER(kIsDifferent, BuildIsDifferent);
02579 REGISTER(kIsEqual, BuildIsEqual);
02580 REGISTER(kIsGreaterOrEqual, BuildIsGreaterOrEqual);
02581 REGISTER(kIsLessOrEqual, BuildIsLessOrEqual);
02582 REGISTER(kIsMember, BuildIsMember);
02583 REGISTER(kLess, BuildLess);
02584 REGISTER(kLessOrEqual, BuildLessOrEqual);
02585 REGISTER(kMapDomain, BuildMapDomain);
02586 REGISTER(kMax, BuildMax);
02587
02588 REGISTER(kMember, BuildMember);
02589 REGISTER(kMin, BuildMin);
02590
02591 REGISTER(kNoCycle, BuildNoCycle);
02592 REGISTER(kNonEqual, BuildNonEqual);
02593 REGISTER(kOpposite, BuildOpposite);
02594 REGISTER(kPack, BuildPack);
02595 REGISTER(kPathCumul, BuildPathCumul);
02596 REGISTER(kPerformedExpr, BuildPerformedExpr);
02597 REGISTER(kProduct, BuildProduct);
02598 REGISTER(kScalProd, BuildScalProd);
02599 REGISTER(kScalProdEqual, BuildScalProdEqual);
02600 REGISTER(kScalProdGreaterOrEqual, BuildScalProdGreaterOrEqual);
02601 REGISTER(kScalProdLessOrEqual, BuildScalProdLessOrEqual);
02602 REGISTER(kSemiContinuous, BuildSemiContinuous);
02603 REGISTER(kSequenceVariable, BuildSequenceVariable);
02604 REGISTER(kSquare, BuildSquare);
02605 REGISTER(kStartExpr, BuildStartExpr);
02606 REGISTER(kSum, BuildSum);
02607 REGISTER(kSumEqual, BuildSumEqual);
02608 REGISTER(kSumGreaterOrEqual, BuildSumGreaterOrEqual);
02609 REGISTER(kSumLessOrEqual, BuildSumLessOrEqual);
02610 REGISTER(kTransition, BuildTransition);
02611 REGISTER(kTrueConstraint, BuildTrueConstraint);
02612 }
02613 #undef REGISTER
02614
02615 void Solver::DeleteBuilders() {
02616 STLDeleteValues(&expression_builders_);
02617 STLDeleteValues(&constraint_builders_);
02618 STLDeleteValues(&interval_builders_);
02619 STLDeleteValues(&sequence_builders_);
02620 }
02621 }