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