00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <vector>
00016
00017 #include "base/commandlineflags.h"
00018 #include "base/integral_types.h"
00019 #include "base/logging.h"
00020 #include "base/scoped_ptr.h"
00021 #include "base/stl_util.h"
00022 #include "constraint_solver/constraint_solver.h"
00023 #include "constraint_solver/constraint_solveri.h"
00024 #include "util/const_int_array.h"
00025 #include "util/const_ptr_array.h"
00026
00027 DECLARE_int32(cache_initial_size);
00028
00029 namespace operations_research {
00030
00031
00032 ModelCache::ModelCache(Solver* const s)
00033 : solver_(s) {}
00034
00035 ModelCache::~ModelCache() {}
00036
00037 Solver* ModelCache::solver() const {
00038 return solver_;
00039 }
00040
00041 namespace {
00042
00043
00044 template <class T> bool IsEqual(const T& a1, const T& a2) {
00045 return a1 == a2;
00046 }
00047
00048 bool IsEqual(const ConstIntArray*& a1, const ConstIntArray*& a2) {
00049 return a1->Equals(*a2);
00050 }
00051
00052 template<class T> bool IsEqual(ConstPtrArray<T>* const a1,
00053 ConstPtrArray<T>* const a2) {
00054 return a1->Equals(*a2);
00055 }
00056
00057 template <class A1, class A2> uint64 Hash2(const A1& a1, const A2& a2) {
00058 uint64 a = Hash1(a1);
00059 uint64 b = GG_ULONGLONG(0xe08c1d668b756f82);
00060 uint64 c = Hash1(a2);
00061 mix(a, b, c);
00062 return c;
00063 }
00064
00065 template <class A1, class A2, class A3> uint64 Hash3(const A1& a1,
00066 const A2& a2,
00067 const A3& a3) {
00068 uint64 a = Hash1(a1);
00069 uint64 b = Hash1(a2);
00070 uint64 c = Hash1(a3);
00071 mix(a, b, c);
00072 return c;
00073 }
00074
00075 template <class A1, class A2, class A3, class A4> uint64 Hash4(const A1& a1,
00076 const A2& a2,
00077 const A3& a3,
00078 const A4& a4) {
00079 uint64 a = Hash1(a1);
00080 uint64 b = Hash1(a2);
00081 uint64 c = Hash2(a3, a4);
00082 mix(a, b, c);
00083 return c;
00084 }
00085
00086 template <class C> void Double(C*** array_ptr, int* size_ptr) {
00087 DCHECK(array_ptr != NULL);
00088 DCHECK(size_ptr != NULL);
00089 C** const old_cell_array = *array_ptr;
00090 const int old_size = *size_ptr;
00091 (*size_ptr) *= 2;
00092 (*array_ptr) = new C*[(*size_ptr)];
00093 memset(*array_ptr, 0, (*size_ptr) * sizeof(**array_ptr));
00094 for (int i = 0; i < old_size; ++i) {
00095 C* tmp = old_cell_array[i];
00096 while (tmp != NULL) {
00097 C* const to_reinsert = tmp;
00098 tmp = tmp->next();
00099 const uint64 position = to_reinsert->Hash() % (*size_ptr);
00100 to_reinsert->set_next((*array_ptr)[position]);
00101 (*array_ptr)[position] = to_reinsert;
00102 }
00103 }
00104 delete [] (old_cell_array);
00105 }
00106
00107
00108
00109 template <class C, class A1> class Cache1 {
00110 public:
00111 Cache1()
00112 : array_(new Cell*[FLAGS_cache_initial_size]),
00113 size_(FLAGS_cache_initial_size),
00114 num_items_(0) {
00115 memset(array_, 0, sizeof(*array_) * size_);
00116 }
00117
00118 ~Cache1() {
00119 for (int i = 0; i < size_; ++i) {
00120 Cell* tmp = array_[i];
00121 while (tmp != NULL) {
00122 Cell* const to_delete = tmp;
00123 tmp = tmp->next();
00124 delete to_delete;
00125 }
00126 }
00127 delete [] array_;
00128 }
00129
00130 C* Find(const A1& a1) const {
00131 uint64 code = Hash1(a1) % size_;
00132 Cell* tmp = array_[code];
00133 while (tmp) {
00134 C* const result = tmp->ReturnsIfEqual(a1);
00135 if (result != NULL) {
00136 return result;
00137 }
00138 tmp = tmp->next();
00139 }
00140 return NULL;
00141 }
00142
00143 void UnsafeInsert(const A1& a1, C* const c) {
00144 const int position = Hash1(a1) % size_;
00145 Cell* const cell = new Cell(a1, c, array_[position]);
00146 array_[position] = cell;
00147 if (++num_items_ > 2 * size_) {
00148 Double(&array_, &size_);
00149 }
00150 }
00151
00152 private:
00153 class Cell {
00154 public:
00155 Cell(const A1& a1, C* const container, Cell* const next)
00156 : a1_(a1), container_(container), next_(next) {}
00157
00158 C* ReturnsIfEqual(const A1& a1) const {
00159 if (IsEqual(a1_, a1)) {
00160 return container_;
00161 }
00162 return NULL;
00163 }
00164
00165 uint64 Hash() const {
00166 return Hash1(a1_);
00167 }
00168
00169 void set_next(Cell* const next) { next_ = next; }
00170
00171 Cell* next() const { return next_; }
00172
00173 private:
00174 const A1 a1_;
00175 C* const container_;
00176 Cell* next_;
00177 };
00178
00179 Cell** array_;
00180 int size_;
00181 int num_items_;
00182 };
00183
00184
00185
00186 template <class C, class A1, class A2> class Cache2 {
00187 public:
00188 Cache2()
00189 : array_(new Cell*[FLAGS_cache_initial_size]),
00190 size_(FLAGS_cache_initial_size),
00191 num_items_(0) {
00192 memset(array_, 0, sizeof(*array_) * size_);
00193 }
00194
00195 ~Cache2() {
00196 for (int i = 0; i < size_; ++i) {
00197 Cell* tmp = array_[i];
00198 while (tmp != NULL) {
00199 Cell* const to_delete = tmp;
00200 tmp = tmp->next();
00201 delete to_delete;
00202 }
00203 }
00204 delete [] array_;
00205 }
00206
00207 C* Find(const A1& a1, const A2& a2) const {
00208 uint64 code = Hash2(a1, a2) % size_;
00209 Cell* tmp = array_[code];
00210 while (tmp) {
00211 C* const result = tmp->ReturnsIfEqual(a1, a2);
00212 if (result != NULL) {
00213 return result;
00214 }
00215 tmp = tmp->next();
00216 }
00217 return NULL;
00218 }
00219
00220 void UnsafeInsert(const A1& a1, const A2& a2, C* const c) {
00221 const int position = Hash2(a1, a2) % size_;
00222 Cell* const cell = new Cell(a1, a2, c, array_[position]);
00223 array_[position] = cell;
00224 if (++num_items_ > 2 * size_) {
00225 Double(&array_, &size_);
00226 }
00227 }
00228
00229 private:
00230 class Cell {
00231 public:
00232 Cell(const A1& a1, const A2& a2, C* const container, Cell* const next)
00233 : a1_(a1), a2_(a2), container_(container), next_(next) {}
00234
00235 C* ReturnsIfEqual(const A1& a1, const A2& a2) const {
00236 if (IsEqual(a1_, a1) && IsEqual(a2_, a2)) {
00237 return container_;
00238 }
00239 return NULL;
00240 }
00241
00242 uint64 Hash() const {
00243 return Hash2(a1_, a2_);
00244 }
00245
00246 void set_next(Cell* const next) { next_ = next; }
00247
00248 Cell* next() const { return next_; }
00249
00250 private:
00251 const A1 a1_;
00252 const A2 a2_;
00253 C* const container_;
00254 Cell* next_;
00255 };
00256
00257 Cell** array_;
00258 int size_;
00259 int num_items_;
00260 };
00261
00262
00263
00264 template <class C, class A1, class A2, class A3> class Cache3 {
00265 public:
00266 Cache3()
00267 : array_(new Cell*[FLAGS_cache_initial_size]),
00268 size_(FLAGS_cache_initial_size),
00269 num_items_(0) {
00270 memset(array_, 0, sizeof(*array_) * size_);
00271 }
00272
00273 ~Cache3() {
00274 for (int i = 0; i < size_; ++i) {
00275 Cell* tmp = array_[i];
00276 while (tmp != NULL) {
00277 Cell* const to_delete = tmp;
00278 tmp = tmp->next();
00279 delete to_delete;
00280 }
00281 }
00282 delete [] array_;
00283 }
00284
00285 C* Find(const A1& a1, const A2& a2, const A3& a3) const {
00286 uint64 code = Hash3(a1, a2, a3) % size_;
00287 Cell* tmp = array_[code];
00288 while (tmp) {
00289 C* const result = tmp->ReturnsIfEqual(a1, a2, a3);
00290 if (result != NULL) {
00291 return result;
00292 }
00293 tmp = tmp->next();
00294 }
00295 return NULL;
00296 }
00297
00298 void UnsafeInsert(const A1& a1, const A2& a2, const A3& a3, C* const c) {
00299 const int position = Hash3(a1, a2, a3) % size_;
00300 Cell* const cell = new Cell(a1, a2, a3, c, array_[position]);
00301 array_[position] = cell;
00302 if (++num_items_ > 2 * size_) {
00303 Double(&array_, &size_);
00304 }
00305 }
00306
00307 private:
00308 class Cell {
00309 public:
00310 Cell(const A1& a1,
00311 const A2& a2,
00312 const A3& a3,
00313 C* const container,
00314 Cell* const next)
00315 : a1_(a1), a2_(a2), a3_(a3), container_(container), next_(next) {}
00316
00317 C* ReturnsIfEqual(const A1& a1, const A2& a2, const A3& a3) const {
00318 if (IsEqual(a1_, a1) && IsEqual(a2_, a2) && IsEqual(a3_, a3)) {
00319 return container_;
00320 }
00321 return NULL;
00322 }
00323
00324 uint64 Hash() const {
00325 return Hash3(a1_, a2_, a3_);
00326 }
00327
00328 void set_next(Cell* const next) { next_ = next; }
00329
00330 Cell* next() const { return next_; }
00331
00332 private:
00333 const A1 a1_;
00334 const A2 a2_;
00335 const A3 a3_;
00336 C* const container_;
00337 Cell* next_;
00338 };
00339
00340 Cell** array_;
00341 int size_;
00342 int num_items_;
00343 };
00344
00345
00346
00347 class NonReversibleCache : public ModelCache {
00348 public:
00349 typedef Cache1<IntExpr, IntVar*> VarIntExprCache;
00350 typedef Cache1<IntExpr, ConstPtrArray<IntVar>*> VarArrayIntExprCache;
00351
00352 typedef Cache2<Constraint, IntVar*, int64> VarConstantConstraintCache;
00353 typedef Cache2<Constraint, IntVar*, IntVar*> VarVarConstraintCache;
00354 typedef Cache2<IntExpr, IntVar*, int64> VarConstantIntExprCache;
00355 typedef Cache2<IntExpr, IntVar*, IntVar*> VarVarIntExprCache;
00356 typedef Cache2<IntExpr, IntVar*, ConstIntArray*> VarConstantArrayIntExprCache;
00357
00358 typedef Cache3<IntExpr, IntVar*, int64, int64>
00359 VarConstantConstantIntExprCache;
00360 typedef Cache3<Constraint, IntVar*, int64, int64>
00361 VarConstantConstantConstraintCache;
00362
00363 explicit NonReversibleCache(Solver* const solver)
00364 : ModelCache(solver),
00365 void_constraints_(VOID_CONSTRAINT_MAX, NULL) {
00366 for (int i = 0; i < VAR_CONSTANT_CONSTRAINT_MAX; ++i) {
00367 var_constant_constraints_.push_back(new VarConstantConstraintCache);
00368 }
00369 for (int i = 0; i < VAR_VAR_CONSTRAINT_MAX; ++i) {
00370 var_var_constraints_.push_back(new VarVarConstraintCache);
00371 }
00372 for (int i = 0; i < VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX; ++i) {
00373 var_constant_constant_constraints_.push_back(
00374 new VarConstantConstantConstraintCache);
00375 }
00376 for (int i = 0; i < VAR_EXPRESSION_MAX; ++i) {
00377 var_expressions_.push_back(new VarIntExprCache);
00378 }
00379 for (int i = 0; i < VAR_CONSTANT_EXPRESSION_MAX; ++i) {
00380 var_constant_expressions_.push_back(new VarConstantIntExprCache);
00381 }
00382 for (int i = 0; i < VAR_VAR_EXPRESSION_MAX; ++i) {
00383 var_var_expressions_.push_back(new VarVarIntExprCache);
00384 }
00385 for (int i = 0; i < VAR_CONSTANT_CONSTANT_EXPRESSION_MAX; ++i) {
00386 var_constant_constant_expressions_.push_back(
00387 new VarConstantConstantIntExprCache);
00388 }
00389 for (int i = 0; i < VAR_CONSTANT_ARRAY_EXPRESSION_MAX; ++i) {
00390 var_constant_array_expressions_.push_back(
00391 new VarConstantArrayIntExprCache);
00392 }
00393 for (int i = 0; i < VAR_ARRAY_EXPRESSION_MAX; ++i) {
00394 var_array_expressions_.push_back(new VarArrayIntExprCache);
00395 }
00396 }
00397
00398 virtual ~NonReversibleCache() {
00399 STLDeleteElements(&var_constant_constraints_);
00400 STLDeleteElements(&var_var_constraints_);
00401 STLDeleteElements(&var_constant_constant_constraints_);
00402 STLDeleteElements(&var_expressions_);
00403 STLDeleteElements(&var_constant_expressions_);
00404 STLDeleteElements(&var_var_expressions_);
00405 STLDeleteElements(&var_constant_constant_expressions_);
00406 STLDeleteElements(&var_constant_array_expressions_);
00407 STLDeleteElements(&var_array_expressions_);
00408 }
00409
00410
00411
00412 virtual Constraint* FindVoidConstraint(VoidConstraintType type) const {
00413 DCHECK_GE(type, 0);
00414 DCHECK_LT(type, VOID_CONSTRAINT_MAX);
00415 return void_constraints_[type];
00416 }
00417
00418 virtual void InsertVoidConstraint(Constraint* const ct,
00419 VoidConstraintType type) {
00420 DCHECK_GE(type, 0);
00421 DCHECK_LT(type, VOID_CONSTRAINT_MAX);
00422 DCHECK(ct != NULL);
00423 if (solver()->state() != Solver::IN_SEARCH) {
00424 void_constraints_[type] = ct;
00425 }
00426 }
00427
00428
00429
00430 virtual Constraint* FindVarConstantConstraint(
00431 IntVar* const var,
00432 int64 value,
00433 VarConstantConstraintType type) const {
00434 DCHECK(var != NULL);
00435 DCHECK_GE(type, 0);
00436 DCHECK_LT(type, VAR_CONSTANT_CONSTRAINT_MAX);
00437 return var_constant_constraints_[type]->Find(var, value);
00438 }
00439
00440 virtual void InsertVarConstantConstraint(
00441 Constraint* const ct,
00442 IntVar* const var,
00443 int64 value,
00444 VarConstantConstraintType type) {
00445 DCHECK(ct != NULL);
00446 DCHECK(var != NULL);
00447 DCHECK_GE(type, 0);
00448 DCHECK_LT(type, VAR_CONSTANT_CONSTRAINT_MAX);
00449 if (solver()->state() != Solver::IN_SEARCH &&
00450 var_constant_constraints_[type]->Find(var, value) == NULL) {
00451 var_constant_constraints_[type]->UnsafeInsert(var, value, ct);
00452 }
00453 }
00454
00455
00456
00457 virtual Constraint* FindVarConstantConstantConstraint(
00458 IntVar* const var,
00459 int64 value1,
00460 int64 value2,
00461 VarConstantConstantConstraintType type) const {
00462 DCHECK(var != NULL);
00463 DCHECK_GE(type, 0);
00464 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX);
00465 return var_constant_constant_constraints_[type]->Find(var, value1, value2);
00466 }
00467
00468 virtual void InsertVarConstantConstantConstraint(
00469 Constraint* const ct,
00470 IntVar* const var,
00471 int64 value1,
00472 int64 value2,
00473 VarConstantConstantConstraintType type) {
00474 DCHECK(ct != NULL);
00475 DCHECK(var != NULL);
00476 DCHECK_GE(type, 0);
00477 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX);
00478 if (solver()->state() != Solver::IN_SEARCH &&
00479 var_constant_constant_constraints_[type]->Find(var,
00480 value1,
00481 value2) == NULL) {
00482 var_constant_constant_constraints_[type]->UnsafeInsert(var,
00483 value1,
00484 value2,
00485 ct);
00486 }
00487 }
00488
00489
00490
00491 virtual Constraint* FindVarVarConstraint(
00492 IntVar* const var1,
00493 IntVar* const var2,
00494 VarVarConstraintType type) const {
00495 DCHECK(var1 != NULL);
00496 DCHECK(var2 != NULL);
00497 DCHECK_GE(type, 0);
00498 DCHECK_LT(type, VAR_VAR_CONSTRAINT_MAX);
00499 return var_var_constraints_[type]->Find(var1, var2);
00500 }
00501
00502 virtual void InsertVarVarConstraint(Constraint* const ct,
00503 IntVar* const var1,
00504 IntVar* const var2,
00505 VarVarConstraintType type) {
00506 DCHECK(ct != NULL);
00507 DCHECK(var1 != NULL);
00508 DCHECK(var2 != NULL);
00509 DCHECK_GE(type, 0);
00510 DCHECK_LT(type, VAR_VAR_CONSTRAINT_MAX);
00511 if (solver()->state() != Solver::IN_SEARCH &&
00512 var_var_constraints_[type]->Find(var1, var2) == NULL) {
00513 var_var_constraints_[type]->UnsafeInsert(var1, var2, ct);
00514 }
00515 }
00516
00517
00518
00519 virtual IntExpr* FindVarExpression(IntVar* const var,
00520 VarExpressionType type) const {
00521 DCHECK(var != NULL);
00522 DCHECK_GE(type, 0);
00523 DCHECK_LT(type, VAR_EXPRESSION_MAX);
00524 return var_expressions_[type]->Find(var);
00525 }
00526
00527 virtual void InsertVarExpression(IntExpr* const expression,
00528 IntVar* const var,
00529 VarExpressionType type) {
00530 DCHECK(expression != NULL);
00531 DCHECK(var != NULL);
00532 DCHECK_GE(type, 0);
00533 DCHECK_LT(type, VAR_EXPRESSION_MAX);
00534 if (solver()->state() != Solver::IN_SEARCH &&
00535 var_expressions_[type]->Find(var) == NULL) {
00536 var_expressions_[type]->UnsafeInsert(var, expression);
00537 }
00538 }
00539
00540
00541
00542 virtual IntExpr* FindVarConstantExpression(
00543 IntVar* const var,
00544 int64 value,
00545 VarConstantExpressionType type) const {
00546 DCHECK(var != NULL);
00547 DCHECK_GE(type, 0);
00548 DCHECK_LT(type, VAR_CONSTANT_EXPRESSION_MAX);
00549 return var_constant_expressions_[type]->Find(var, value);
00550 }
00551
00552 virtual void InsertVarConstantExpression(
00553 IntExpr* const expression,
00554 IntVar* const var,
00555 int64 value,
00556 VarConstantExpressionType type) {
00557 DCHECK(expression != NULL);
00558 DCHECK(var != NULL);
00559 DCHECK_GE(type, 0);
00560 DCHECK_LT(type, VAR_CONSTANT_EXPRESSION_MAX);
00561 if (solver()->state() != Solver::IN_SEARCH &&
00562 var_constant_expressions_[type]->Find(var, value) == NULL) {
00563 var_constant_expressions_[type]->UnsafeInsert(var, value, expression);
00564 }
00565 }
00566
00567
00568
00569 virtual IntExpr* FindVarVarExpression(
00570 IntVar* const var1,
00571 IntVar* const var2,
00572 VarVarExpressionType type) const {
00573 DCHECK(var1 != NULL);
00574 DCHECK(var2 != NULL);
00575 DCHECK_GE(type, 0);
00576 DCHECK_LT(type, VAR_VAR_EXPRESSION_MAX);
00577 return var_var_expressions_[type]->Find(var1, var2);
00578 }
00579
00580 virtual void InsertVarVarExpression(
00581 IntExpr* const expression,
00582 IntVar* const var1,
00583 IntVar* const var2,
00584 VarVarExpressionType type) {
00585 DCHECK(expression != NULL);
00586 DCHECK(var1 != NULL);
00587 DCHECK(var2 != NULL);
00588 DCHECK_GE(type, 0);
00589 DCHECK_LT(type, VAR_VAR_EXPRESSION_MAX);
00590 if (solver()->state() != Solver::IN_SEARCH &&
00591 var_var_expressions_[type]->Find(var1, var2) == NULL) {
00592 var_var_expressions_[type]->UnsafeInsert(var1, var2, expression);
00593 }
00594 }
00595
00596
00597
00598 virtual IntExpr* FindVarConstantConstantExpression(
00599 IntVar* const var,
00600 int64 value1,
00601 int64 value2,
00602 VarConstantConstantExpressionType type) const {
00603 DCHECK(var != NULL);
00604 DCHECK_GE(type, 0);
00605 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_EXPRESSION_MAX);
00606 return var_constant_constant_expressions_[type]->Find(var, value1, value2);
00607 }
00608
00609 virtual void InsertVarConstantConstantExpression(
00610 IntExpr* const expression,
00611 IntVar* const var,
00612 int64 value1,
00613 int64 value2,
00614 VarConstantConstantExpressionType type) {
00615 DCHECK(expression != NULL);
00616 DCHECK(var != NULL);
00617 DCHECK_GE(type, 0);
00618 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_EXPRESSION_MAX);
00619 if (solver()->state() != Solver::IN_SEARCH &&
00620 var_constant_constant_expressions_[type]->Find(var,
00621 value1,
00622 value2) == NULL) {
00623 var_constant_constant_expressions_[type]->UnsafeInsert(var,
00624 value1,
00625 value2,
00626 expression);
00627 }
00628 }
00629
00630
00631
00632 virtual IntExpr* FindVarConstantArrayExpression(
00633 IntVar* const var,
00634 ConstIntArray* const values,
00635 VarConstantArrayExpressionType type) const {
00636 DCHECK(var != NULL);
00637 DCHECK_GE(type, 0);
00638 DCHECK_LT(type, VAR_CONSTANT_ARRAY_EXPRESSION_MAX);
00639 return var_constant_array_expressions_[type]->Find(var, values);
00640 }
00641
00642 virtual void InsertVarConstantArrayExpression(
00643 IntExpr* const expression,
00644 IntVar* const var,
00645 ConstIntArray* const values,
00646 VarConstantArrayExpressionType type) {
00647 DCHECK(expression != NULL);
00648 DCHECK(var != NULL);
00649 DCHECK_GE(type, 0);
00650 DCHECK_LT(type, VAR_CONSTANT_ARRAY_EXPRESSION_MAX);
00651 if (solver()->state() != Solver::IN_SEARCH &&
00652 var_constant_array_expressions_[type]->Find(var, values) == NULL) {
00653 var_constant_array_expressions_[type]->UnsafeInsert(var,
00654 values,
00655 expression);
00656 }
00657 }
00658
00659
00660
00661 virtual IntExpr* FindVarArrayExpression(
00662 ConstPtrArray<IntVar>* const vars,
00663 VarArrayExpressionType type) const {
00664 DCHECK_GE(type, 0);
00665 DCHECK_LT(type, VAR_ARRAY_EXPRESSION_MAX);
00666 return var_array_expressions_[type]->Find(vars);
00667 }
00668
00669 virtual void InsertVarArrayExpression(
00670 IntExpr* const expression,
00671 ConstPtrArray<IntVar>* const vars,
00672 VarArrayExpressionType type) {
00673 DCHECK(expression != NULL);
00674 DCHECK_GE(type, 0);
00675 DCHECK_LT(type, VAR_ARRAY_EXPRESSION_MAX);
00676 if (solver()->state() != Solver::IN_SEARCH &&
00677 var_array_expressions_[type]->Find(vars) == NULL) {
00678 var_array_expressions_[type]->UnsafeInsert(vars, expression);
00679 }
00680 }
00681
00682 private:
00683 std::vector<Constraint*> void_constraints_;
00684 std::vector<VarConstantConstraintCache*> var_constant_constraints_;
00685 std::vector<VarVarConstraintCache*> var_var_constraints_;
00686 std::vector<VarConstantConstantConstraintCache*>
00687 var_constant_constant_constraints_;
00688 std::vector<VarIntExprCache*> var_expressions_;
00689 std::vector<VarConstantIntExprCache*> var_constant_expressions_;
00690 std::vector<VarVarIntExprCache*> var_var_expressions_;
00691 std::vector<VarConstantConstantIntExprCache*> var_constant_constant_expressions_;
00692 std::vector<VarConstantArrayIntExprCache*> var_constant_array_expressions_;
00693 std::vector<VarArrayIntExprCache*> var_array_expressions_;
00694 };
00695 }
00696
00697 ModelCache* BuildModelCache(Solver* const solver) {
00698 return new NonReversibleCache(solver);
00699 }
00700
00701 ModelCache* Solver::Cache() const {
00702 return model_cache_.get();
00703 }
00704 }