00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <gecode/minimodel.hh>
00039 #include <gecode/int/linear.hh>
00040
00041 namespace Gecode {
00042
00044 class LinIntExpr::Node {
00045 public:
00047 unsigned int use;
00049 int n_int;
00051 int n_bool;
00053 NodeType t;
00055 Node *l, *r;
00057 union {
00059 Int::Linear::Term<Int::IntView>* ti;
00061 Int::Linear::Term<Int::BoolView>* tb;
00063 NonLinIntExpr* ne;
00064 } sum;
00066 int a, c;
00068 IntVar x_int;
00070 BoolVar x_bool;
00072 Node(void);
00074 void fill(Home home, IntConLevel icl,
00075 Int::Linear::Term<Int::IntView>*& ti,
00076 Int::Linear::Term<Int::BoolView>*& tb,
00077 long long int m, long long int& d) const;
00079 int fill(Home home, IntConLevel icl,
00080 Int::Linear::Term<Int::IntView>* ti,
00081 Int::Linear::Term<Int::BoolView>* tb) const;
00083 bool decrement(void);
00085 ~Node(void);
00087 static void* operator new(size_t size);
00089 static void operator delete(void* p,size_t size);
00090 };
00091
00092
00093
00094
00095
00096 forceinline
00097 LinIntExpr::Node::Node(void) : use(1) {
00098 }
00099
00100 forceinline
00101 LinIntExpr::Node::~Node(void) {
00102 switch (t) {
00103 case NT_SUM_INT:
00104 if (n_int > 0)
00105 heap.free<Int::Linear::Term<Int::IntView> >(sum.ti,n_int);
00106 break;
00107 case NT_SUM_BOOL:
00108 if (n_bool > 0)
00109 heap.free<Int::Linear::Term<Int::BoolView> >(sum.tb,n_bool);
00110 break;
00111 case NT_NONLIN:
00112 delete sum.ne;
00113 break;
00114 default: ;
00115 }
00116 }
00117
00118 forceinline void*
00119 LinIntExpr::Node::operator new(size_t size) {
00120 return heap.ralloc(size);
00121 }
00122
00123 forceinline void
00124 LinIntExpr::Node::operator delete(void* p, size_t) {
00125 heap.rfree(p);
00126 }
00127 bool
00128 LinIntExpr::Node::decrement(void) {
00129 if (--use == 0) {
00130 if ((l != NULL) && l->decrement())
00131 delete l;
00132 if ((r != NULL) && r->decrement())
00133 delete r;
00134 return true;
00135 }
00136 return false;
00137 }
00138
00139
00140
00141
00142
00143
00144 LinIntExpr::LinIntExpr(const LinIntExpr& e)
00145 : n(e.n) {
00146 n->use++;
00147 }
00148
00149 int
00150 LinIntExpr::Node::fill(Home home, IntConLevel icl,
00151 Int::Linear::Term<Int::IntView>* ti,
00152 Int::Linear::Term<Int::BoolView>* tb) const {
00153 long long int d=0;
00154 fill(home,icl,ti,tb,1,d);
00155 Int::Limits::check(d,"MiniModel::LinIntExpr");
00156 return static_cast<int>(d);
00157 }
00158
00159 void
00160 LinIntExpr::post(Home home, IntRelType irt, IntConLevel icl) const {
00161 if (home.failed()) return;
00162 Region r(home);
00163 if (n->n_bool == 0) {
00164
00165 if (n->t==NT_ADD && n->l == NULL && n->r->t==NT_NONLIN) {
00166 n->r->sum.ne->post(home,irt,-n->c,icl);
00167 } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==NULL) {
00168 switch (irt) {
00169 case IRT_LQ: irt=IRT_GQ; break;
00170 case IRT_LE: irt=IRT_GR; break;
00171 case IRT_GQ: irt=IRT_LQ; break;
00172 case IRT_GR: irt=IRT_LE; break;
00173 default: break;
00174 }
00175 n->r->sum.ne->post(home,irt,n->c,icl);
00176 } else if (irt==IRT_EQ &&
00177 n->t==NT_SUB && n->r->t==NT_NONLIN &&
00178 n->l != NULL && n->l->t==NT_VAR_INT
00179 && n->l->a==1) {
00180 (void) n->r->sum.ne->post(home,&n->l->x_int,icl);
00181 } else if (irt==IRT_EQ &&
00182 n->t==NT_SUB && n->r->t==NT_VAR_INT &&
00183 n->l != NULL && n->l->t==NT_NONLIN
00184 && n->r->a==1) {
00185 (void) n->l->sum.ne->post(home,&n->r->x_int,icl);
00186 } else {
00187 Int::Linear::Term<Int::IntView>* its =
00188 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
00189 int c = n->fill(home,icl,its,NULL);
00190 Int::Linear::post(home, its, n->n_int, irt, -c, icl);
00191 }
00192 } else if (n->n_int == 0) {
00193
00194 Int::Linear::Term<Int::BoolView>* bts =
00195 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00196 int c = n->fill(home,icl,NULL,bts);
00197 Int::Linear::post(home, bts, n->n_bool, irt, -c, icl);
00198 } else if (n->n_bool == 1) {
00199
00200 Int::Linear::Term<Int::IntView>* its =
00201 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
00202 Int::Linear::Term<Int::BoolView>* bts =
00203 r.alloc<Int::Linear::Term<Int::BoolView> >(1);
00204 int c = n->fill(home,icl,its,bts);
00205 IntVar x(home,0,1);
00206 channel(home,bts[0].x,x);
00207 its[n->n_int].x = x;
00208 its[n->n_int].a = bts[0].a;
00209 Int::Linear::post(home, its, n->n_int+1, irt, -c, icl);
00210 } else {
00211
00212 Int::Linear::Term<Int::IntView>* its =
00213 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
00214 Int::Linear::Term<Int::BoolView>* bts =
00215 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00216 int c = n->fill(home,icl,its,bts);
00217 int min, max;
00218 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
00219 IntVar x(home,min,max);
00220 its[n->n_int].x = x; its[n->n_int].a = 1;
00221 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, icl);
00222 Int::Linear::post(home, its, n->n_int+1, irt, -c, icl);
00223 }
00224 }
00225
00226 void
00227 LinIntExpr::post(Home home, IntRelType irt, const BoolVar& b,
00228 IntConLevel icl) const {
00229 if (home.failed()) return;
00230 Region r(home);
00231 if (n->n_bool == 0) {
00232
00233 if (n->t==NT_ADD && n->l==NULL && n->r->t==NT_NONLIN) {
00234 n->r->sum.ne->post(home,irt,-n->c,b,icl);
00235 } else if (n->t==NT_SUB && n->l==NULL && n->r->t==NT_NONLIN) {
00236 switch (irt) {
00237 case IRT_LQ: irt=IRT_GQ; break;
00238 case IRT_LE: irt=IRT_GR; break;
00239 case IRT_GQ: irt=IRT_LQ; break;
00240 case IRT_GR: irt=IRT_LE; break;
00241 default: break;
00242 }
00243 n->r->sum.ne->post(home,irt,n->c,b,icl);
00244 } else {
00245 Int::Linear::Term<Int::IntView>* its =
00246 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
00247 int c = n->fill(home,icl,its,NULL);
00248 Int::Linear::post(home, its, n->n_int, irt, -c, b, icl);
00249 }
00250 } else if (n->n_int == 0) {
00251
00252 Int::Linear::Term<Int::BoolView>* bts =
00253 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00254 int c = n->fill(home,icl,NULL,bts);
00255 Int::Linear::post(home, bts, n->n_bool, irt, -c, b, icl);
00256 } else if (n->n_bool == 1) {
00257
00258 Int::Linear::Term<Int::IntView>* its =
00259 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
00260 Int::Linear::Term<Int::BoolView>* bts =
00261 r.alloc<Int::Linear::Term<Int::BoolView> >(1);
00262 int c = n->fill(home,icl,its,bts);
00263 IntVar x(home,0,1);
00264 channel(home,bts[0].x,x);
00265 its[n->n_int].x = x;
00266 its[n->n_int].a = bts[0].a;
00267 Int::Linear::post(home, its, n->n_int+1, irt, -c, b, icl);
00268 } else {
00269
00270 Int::Linear::Term<Int::IntView>* its =
00271 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
00272 Int::Linear::Term<Int::BoolView>* bts =
00273 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00274 int c = n->fill(home,icl,its,bts);
00275 int min, max;
00276 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
00277 IntVar x(home,min,max);
00278 its[n->n_int].x = x; its[n->n_int].a = 1;
00279 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, icl);
00280 Int::Linear::post(home, its, n->n_int+1, irt, -c, b, icl);
00281 }
00282 }
00283
00284 IntVar
00285 LinIntExpr::post(Home home, IntConLevel icl) const {
00286 if (home.failed()) return IntVar(home,0,0);
00287 Region r(home);
00288 if (n->n_bool == 0) {
00289
00290 Int::Linear::Term<Int::IntView>* its =
00291 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
00292 int c = n->fill(home,icl,its,NULL);
00293 if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
00294 return its[0].x;
00295 int min, max;
00296 Int::Linear::estimate(&its[0],n->n_int,c,min,max);
00297 IntVar x(home, min, max);
00298 its[n->n_int].x = x; its[n->n_int].a = -1;
00299 Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c, icl);
00300 return x;
00301 } else if (n->n_int == 0) {
00302
00303 Int::Linear::Term<Int::BoolView>* bts =
00304 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00305 int c = n->fill(home,icl,NULL,bts);
00306 int min, max;
00307 Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
00308 IntVar x(home, min, max);
00309 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c, icl);
00310 return x;
00311 } else if (n->n_bool == 1) {
00312
00313 Int::Linear::Term<Int::IntView>* its =
00314 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
00315 Int::Linear::Term<Int::BoolView>* bts =
00316 r.alloc<Int::Linear::Term<Int::BoolView> >(1);
00317 int c = n->fill(home,icl,its,bts);
00318 IntVar x(home, 0, 1);
00319 channel(home, x, bts[0].x);
00320 its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
00321 int y_min, y_max;
00322 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
00323 IntVar y(home, y_min, y_max);
00324 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
00325 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, icl);
00326 return y;
00327 } else {
00328
00329 Int::Linear::Term<Int::IntView>* its =
00330 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
00331 Int::Linear::Term<Int::BoolView>* bts =
00332 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
00333 int c = n->fill(home,icl,its,bts);
00334 int x_min, x_max;
00335 Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
00336 IntVar x(home, x_min, x_max);
00337 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, icl);
00338 its[n->n_int].x = x; its[n->n_int].a = 1;
00339 int y_min, y_max;
00340 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
00341 IntVar y(home, y_min, y_max);
00342 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
00343 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, icl);
00344 return y;
00345 }
00346 }
00347
00348 NonLinIntExpr*
00349 LinIntExpr::nle(void) const {
00350 return n->t == NT_NONLIN ? n->sum.ne : NULL;
00351 }
00352
00353 LinIntExpr::LinIntExpr(void) :
00354 n(new Node) {
00355 n->n_int = n->n_bool = 0;
00356 n->t = NT_VAR_INT;
00357 n->l = n->r = NULL;
00358 n->a = 0;
00359 }
00360
00361 LinIntExpr::LinIntExpr(int c) :
00362 n(new Node) {
00363 n->n_int = n->n_bool = 0;
00364 n->t = NT_CONST;
00365 n->l = n->r = NULL;
00366 n->a = 0;
00367 Int::Limits::check(c,"MiniModel::LinIntExpr");
00368 n->c = c;
00369 }
00370
00371 LinIntExpr::LinIntExpr(const IntVar& x, int a) :
00372 n(new Node) {
00373 n->n_int = 1;
00374 n->n_bool = 0;
00375 n->t = NT_VAR_INT;
00376 n->l = n->r = NULL;
00377 n->a = a;
00378 n->x_int = x;
00379 }
00380
00381 LinIntExpr::LinIntExpr(const BoolVar& x, int a) :
00382 n(new Node) {
00383 n->n_int = 0;
00384 n->n_bool = 1;
00385 n->t = NT_VAR_BOOL;
00386 n->l = n->r = NULL;
00387 n->a = a;
00388 n->x_bool = x;
00389 }
00390
00391 LinIntExpr::LinIntExpr(const IntVarArgs& x) :
00392 n(new Node) {
00393 n->n_int = x.size();
00394 n->n_bool = 0;
00395 n->t = NT_SUM_INT;
00396 n->l = n->r = NULL;
00397 if (x.size() > 0) {
00398 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
00399 for (int i=x.size(); i--; ) {
00400 n->sum.ti[i].x = x[i];
00401 n->sum.ti[i].a = 1;
00402 }
00403 }
00404 }
00405
00406 LinIntExpr::LinIntExpr(const IntArgs& a, const IntVarArgs& x) :
00407 n(new Node) {
00408 if (a.size() != x.size())
00409 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
00410 n->n_int = x.size();
00411 n->n_bool = 0;
00412 n->t = NT_SUM_INT;
00413 n->l = n->r = NULL;
00414 if (x.size() > 0) {
00415 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
00416 for (int i=x.size(); i--; ) {
00417 n->sum.ti[i].x = x[i];
00418 n->sum.ti[i].a = a[i];
00419 }
00420 }
00421 }
00422
00423 LinIntExpr::LinIntExpr(const BoolVarArgs& x) :
00424 n(new Node) {
00425 n->n_int = 0;
00426 n->n_bool = x.size();
00427 n->t = NT_SUM_BOOL;
00428 n->l = n->r = NULL;
00429 if (x.size() > 0) {
00430 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
00431 for (int i=x.size(); i--; ) {
00432 n->sum.tb[i].x = x[i];
00433 n->sum.tb[i].a = 1;
00434 }
00435 }
00436 }
00437
00438 LinIntExpr::LinIntExpr(const IntArgs& a, const BoolVarArgs& x) :
00439 n(new Node) {
00440 if (a.size() != x.size())
00441 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
00442 n->n_int = 0;
00443 n->n_bool = x.size();
00444 n->t = NT_SUM_BOOL;
00445 n->l = n->r = NULL;
00446 if (x.size() > 0) {
00447 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
00448 for (int i=x.size(); i--; ) {
00449 n->sum.tb[i].x = x[i];
00450 n->sum.tb[i].a = a[i];
00451 }
00452 }
00453 }
00454
00455 LinIntExpr::LinIntExpr(const LinIntExpr& e0, NodeType t, const LinIntExpr& e1) :
00456 n(new Node) {
00457 n->n_int = e0.n->n_int + e1.n->n_int;
00458 n->n_bool = e0.n->n_bool + e1.n->n_bool;
00459 n->t = t;
00460 n->l = e0.n; n->l->use++;
00461 n->r = e1.n; n->r->use++;
00462 }
00463
00464 LinIntExpr::LinIntExpr(const LinIntExpr& e, NodeType t, int c) :
00465 n(new Node) {
00466 n->n_int = e.n->n_int;
00467 n->n_bool = e.n->n_bool;
00468 n->t = t;
00469 n->l = NULL;
00470 n->r = e.n; n->r->use++;
00471 n->c = c;
00472 }
00473
00474 LinIntExpr::LinIntExpr(int a, const LinIntExpr& e) :
00475 n(new Node) {
00476 n->n_int = e.n->n_int;
00477 n->n_bool = e.n->n_bool;
00478 n->t = NT_MUL;
00479 n->l = e.n; n->l->use++;
00480 n->r = NULL;
00481 n->a = a;
00482 }
00483
00484 LinIntExpr::LinIntExpr(NonLinIntExpr* e) :
00485 n(new Node) {
00486 n->n_int = 1;
00487 n->n_bool = 0;
00488 n->t = NT_NONLIN;
00489 n->l = n->r = NULL;
00490 n->a = 0;
00491 n->sum.ne = e;
00492 }
00493
00494 const LinIntExpr&
00495 LinIntExpr::operator =(const LinIntExpr& e) {
00496 if (this != &e) {
00497 if (n->decrement())
00498 delete n;
00499 n = e.n; n->use++;
00500 }
00501 return *this;
00502 }
00503
00504 LinIntExpr::~LinIntExpr(void) {
00505 if (n->decrement())
00506 delete n;
00507 }
00508
00509
00510 void
00511 LinIntExpr::Node::fill(Home home, IntConLevel icl,
00512 Int::Linear::Term<Int::IntView>*& ti,
00513 Int::Linear::Term<Int::BoolView>*& tb,
00514 long long int m, long long int& d) const {
00515 switch (this->t) {
00516 case NT_CONST:
00517 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
00518 d += m*c;
00519 break;
00520 case NT_VAR_INT:
00521 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
00522 ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
00523 break;
00524 case NT_NONLIN:
00525 ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, NULL, icl); ti++;
00526 break;
00527 case NT_VAR_BOOL:
00528 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
00529 tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
00530 break;
00531 case NT_SUM_INT:
00532 for (int i=n_int; i--; ) {
00533 Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
00534 ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
00535 }
00536 ti += n_int;
00537 break;
00538 case NT_SUM_BOOL:
00539 for (int i=n_bool; i--; ) {
00540 Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
00541 tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
00542 }
00543 tb += n_bool;
00544 break;
00545 case NT_ADD:
00546 if (l == NULL) {
00547 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
00548 d += m*c;
00549 } else {
00550 l->fill(home,icl,ti,tb,m,d);
00551 }
00552 r->fill(home,icl,ti,tb,m,d);
00553 break;
00554 case NT_SUB:
00555 if (l == NULL) {
00556 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
00557 d += m*c;
00558 } else {
00559 l->fill(home,icl,ti,tb,m,d);
00560 }
00561 r->fill(home,icl,ti,tb,-m,d);
00562 break;
00563 case NT_MUL:
00564 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
00565 l->fill(home,icl,ti,tb,m*a,d);
00566 break;
00567 default:
00568 GECODE_NEVER;
00569 }
00570 }
00571
00572
00573
00574
00575
00576
00577 LinIntExpr
00578 operator +(int c, const IntVar& x) {
00579 if (x.assigned() &&
00580 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
00581 return LinIntExpr(c+x.val());
00582 else
00583 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
00584 }
00585 LinIntExpr
00586 operator +(int c, const BoolVar& x) {
00587 if (x.assigned() &&
00588 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
00589 return LinIntExpr(c+x.val());
00590 else
00591 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
00592 }
00593 LinIntExpr
00594 operator +(int c, const LinIntExpr& e) {
00595 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
00596 }
00597 LinIntExpr
00598 operator +(const IntVar& x, int c) {
00599 if (x.assigned() &&
00600 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
00601 return LinIntExpr(c+x.val());
00602 else
00603 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
00604 }
00605 LinIntExpr
00606 operator +(const BoolVar& x, int c) {
00607 if (x.assigned() &&
00608 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
00609 return LinIntExpr(c+x.val());
00610 else
00611 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
00612 }
00613 LinIntExpr
00614 operator +(const LinIntExpr& e, int c) {
00615 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
00616 }
00617 LinIntExpr
00618 operator +(const IntVar& x, const IntVar& y) {
00619 if (x.assigned())
00620 return x.val() + y;
00621 else if (y.assigned())
00622 return x + y.val();
00623 else
00624 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
00625 }
00626 LinIntExpr
00627 operator +(const IntVar& x, const BoolVar& y) {
00628 if (x.assigned())
00629 return x.val() + y;
00630 else if (y.assigned())
00631 return x + y.val();
00632 else
00633 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
00634 }
00635 LinIntExpr
00636 operator +(const BoolVar& x, const IntVar& y) {
00637 if (x.assigned())
00638 return x.val() + y;
00639 else if (y.assigned())
00640 return x + y.val();
00641 else
00642 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
00643 }
00644 LinIntExpr
00645 operator +(const BoolVar& x, const BoolVar& y) {
00646 if (x.assigned())
00647 return x.val() + y;
00648 else if (y.assigned())
00649 return x + y.val();
00650 else
00651 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
00652 }
00653 LinIntExpr
00654 operator +(const IntVar& x, const LinIntExpr& e) {
00655 if (x.assigned())
00656 return x.val() + e;
00657 else
00658 return LinIntExpr(x,LinIntExpr::NT_ADD,e);
00659 }
00660 LinIntExpr
00661 operator +(const BoolVar& x, const LinIntExpr& e) {
00662 if (x.assigned())
00663 return x.val() + e;
00664 else
00665 return LinIntExpr(x,LinIntExpr::NT_ADD,e);
00666 }
00667 LinIntExpr
00668 operator +(const LinIntExpr& e, const IntVar& x) {
00669 if (x.assigned())
00670 return e + x.val();
00671 else
00672 return LinIntExpr(e,LinIntExpr::NT_ADD,x);
00673 }
00674 LinIntExpr
00675 operator +(const LinIntExpr& e, const BoolVar& x) {
00676 if (x.assigned())
00677 return e + x.val();
00678 else
00679 return LinIntExpr(e,LinIntExpr::NT_ADD,x);
00680 }
00681 LinIntExpr
00682 operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
00683 return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
00684 }
00685
00686 LinIntExpr
00687 operator -(int c, const IntVar& x) {
00688 if (x.assigned() &&
00689 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
00690 return LinIntExpr(c-x.val());
00691 else
00692 return LinIntExpr(x,LinIntExpr::NT_SUB,c);
00693 }
00694 LinIntExpr
00695 operator -(int c, const BoolVar& x) {
00696 if (x.assigned() &&
00697 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
00698 return LinIntExpr(c-x.val());
00699 else
00700 return LinIntExpr(x,LinIntExpr::NT_SUB,c);
00701 }
00702 LinIntExpr
00703 operator -(int c, const LinIntExpr& e) {
00704 return LinIntExpr(e,LinIntExpr::NT_SUB,c);
00705 }
00706 LinIntExpr
00707 operator -(const IntVar& x, int c) {
00708 if (x.assigned() &&
00709 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
00710 return LinIntExpr(x.val()-c);
00711 else
00712 return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
00713 }
00714 LinIntExpr
00715 operator -(const BoolVar& x, int c) {
00716 if (x.assigned() &&
00717 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
00718 return LinIntExpr(x.val()-c);
00719 else
00720 return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
00721 }
00722 LinIntExpr
00723 operator -(const LinIntExpr& e, int c) {
00724 return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
00725 }
00726 LinIntExpr
00727 operator -(const IntVar& x, const IntVar& y) {
00728 if (x.assigned())
00729 return x.val() - y;
00730 else if (y.assigned())
00731 return x - y.val();
00732 else
00733 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
00734 }
00735 LinIntExpr
00736 operator -(const IntVar& x, const BoolVar& y) {
00737 if (x.assigned())
00738 return x.val() - y;
00739 else if (y.assigned())
00740 return x - y.val();
00741 else
00742 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
00743 }
00744 LinIntExpr
00745 operator -(const BoolVar& x, const IntVar& y) {
00746 if (x.assigned())
00747 return x.val() - y;
00748 else if (y.assigned())
00749 return x - y.val();
00750 else
00751 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
00752 }
00753 LinIntExpr
00754 operator -(const BoolVar& x, const BoolVar& y) {
00755 if (x.assigned())
00756 return x.val() - y;
00757 else if (y.assigned())
00758 return x - y.val();
00759 else
00760 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
00761 }
00762 LinIntExpr
00763 operator -(const IntVar& x, const LinIntExpr& e) {
00764 if (x.assigned())
00765 return x.val() - e;
00766 else
00767 return LinIntExpr(x,LinIntExpr::NT_SUB,e);
00768 }
00769 LinIntExpr
00770 operator -(const BoolVar& x, const LinIntExpr& e) {
00771 if (x.assigned())
00772 return x.val() - e;
00773 else
00774 return LinIntExpr(x,LinIntExpr::NT_SUB,e);
00775 }
00776 LinIntExpr
00777 operator -(const LinIntExpr& e, const IntVar& x) {
00778 if (x.assigned())
00779 return e - x.val();
00780 else
00781 return LinIntExpr(e,LinIntExpr::NT_SUB,x);
00782 }
00783 LinIntExpr
00784 operator -(const LinIntExpr& e, const BoolVar& x) {
00785 if (x.assigned())
00786 return e - x.val();
00787 else
00788 return LinIntExpr(e,LinIntExpr::NT_SUB,x);
00789 }
00790 LinIntExpr
00791 operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
00792 return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
00793 }
00794
00795 LinIntExpr
00796 operator -(const IntVar& x) {
00797 if (x.assigned())
00798 return LinIntExpr(-x.val());
00799 else
00800 return LinIntExpr(x,LinIntExpr::NT_SUB,0);
00801 }
00802 LinIntExpr
00803 operator -(const BoolVar& x) {
00804 if (x.assigned())
00805 return LinIntExpr(-x.val());
00806 else
00807 return LinIntExpr(x,LinIntExpr::NT_SUB,0);
00808 }
00809 LinIntExpr
00810 operator -(const LinIntExpr& e) {
00811 return LinIntExpr(e,LinIntExpr::NT_SUB,0);
00812 }
00813
00814 LinIntExpr
00815 operator *(int a, const IntVar& x) {
00816 if (a == 0)
00817 return LinIntExpr(0.0);
00818 else if (x.assigned() &&
00819 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
00820 return LinIntExpr(a*x.val());
00821 else
00822 return LinIntExpr(x,a);
00823 }
00824 LinIntExpr
00825 operator *(int a, const BoolVar& x) {
00826 if (a == 0)
00827 return LinIntExpr(0.0);
00828 else if (x.assigned() &&
00829 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
00830 return LinIntExpr(a*x.val());
00831 else
00832 return LinIntExpr(x,a);
00833 }
00834 LinIntExpr
00835 operator *(const IntVar& x, int a) {
00836 if (a == 0)
00837 return LinIntExpr(0.0);
00838 else if (x.assigned() &&
00839 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
00840 return LinIntExpr(a*x.val());
00841 else
00842 return LinIntExpr(x,a);
00843 }
00844 LinIntExpr
00845 operator *(const BoolVar& x, int a) {
00846 if (a == 0)
00847 return LinIntExpr(0.0);
00848 else if (x.assigned() &&
00849 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
00850 return LinIntExpr(a*x.val());
00851 else
00852 return LinIntExpr(x,a);
00853 }
00854 LinIntExpr
00855 operator *(const LinIntExpr& e, int a) {
00856 if (a == 0)
00857 return LinIntExpr(0.0);
00858 else
00859 return LinIntExpr(a,e);
00860 }
00861 LinIntExpr
00862 operator *(int a, const LinIntExpr& e) {
00863 if (a == 0)
00864 return LinIntExpr(0.0);
00865 else
00866 return LinIntExpr(a,e);
00867 }
00868
00869 LinIntExpr
00870 sum(const IntVarArgs& x) {
00871 return LinIntExpr(x);
00872 }
00873 LinIntExpr
00874 sum(const IntArgs& a, const IntVarArgs& x) {
00875 return LinIntExpr(a,x);
00876 }
00877 LinIntExpr
00878 sum(const BoolVarArgs& x) {
00879 return LinIntExpr(x);
00880 }
00881 LinIntExpr
00882 sum(const IntArgs& a, const BoolVarArgs& x) {
00883 return LinIntExpr(a,x);
00884 }
00885 LinIntExpr
00886 sum(const Slice<IntArgs>& slice) {
00887 const Slice<IntArgs>::ArgsType & args = slice;
00888 return sum(args);
00889 }
00890 LinIntExpr
00891 sum(const Matrix<IntArgs>& matrix) {
00892 const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
00893 return sum(args);
00894 }
00895 LinIntExpr
00896 sum(const IntArgs& args) {
00897 int i, sum = 0;
00898 const int size = args.size();
00899
00900 for (i = 0 ; i < size ; ++i)
00901 {
00902 sum += args[i];
00903 }
00904
00905 return LinIntExpr(sum);
00906 }
00907
00908
00909 IntVar
00910 expr(Home home, const LinIntExpr& e, IntConLevel icl) {
00911 if (!home.failed())
00912 return e.post(home,icl);
00913 IntVar x(home,Int::Limits::min,Int::Limits::max);
00914 return x;
00915 }
00916
00917 }
00918
00919