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