lin-expr.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Christian Schulte <schulte@gecode.org> 00005 * 00006 * Copyright: 00007 * Christian Schulte, 2010 00008 * 00009 * Last modified: 00010 * $Date: 2010-07-14 20:32:01 +0200 (Wed, 14 Jul 2010) $ by $Author: schulte $ 00011 * $Revision: 11195 $ 00012 * 00013 * This file is part of Gecode, the generic constraint 00014 * development environment: 00015 * http://www.gecode.org 00016 * 00017 * Permission is hereby granted, free of charge, to any person obtaining 00018 * a copy of this software and associated documentation files (the 00019 * "Software"), to deal in the Software without restriction, including 00020 * without limitation the rights to use, copy, modify, merge, publish, 00021 * distribute, sublicense, and/or sell copies of the Software, and to 00022 * permit persons to whom the Software is furnished to do so, subject to 00023 * the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be 00026 * included in all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00029 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00031 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00032 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00033 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00034 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00035 * 00036 */ 00037 00038 #include <gecode/minimodel.hh> 00039 00040 namespace Gecode { 00041 00042 bool 00043 LinExpr::Node::decrement(void) { 00044 if (--use == 0) { 00045 if ((l != NULL) && l->decrement()) 00046 delete l; 00047 if ((r != NULL) && r->decrement()) 00048 delete r; 00049 return true; 00050 } 00051 return false; 00052 } 00053 00054 /* 00055 * Operations for expressions 00056 * 00057 */ 00058 00059 const LinExpr& 00060 LinExpr::operator =(const LinExpr& e) { 00061 if (this != &e) { 00062 if (n->decrement()) 00063 delete n; 00064 n = e.n; n->use++; 00065 } 00066 return *this; 00067 } 00068 00069 LinExpr::~LinExpr(void) { 00070 if (n->decrement()) 00071 delete n; 00072 } 00073 00074 00075 void 00076 LinExpr::Node::fill(Home home, IntConLevel icl, 00077 Int::Linear::Term<Int::IntView>*& ti, 00078 Int::Linear::Term<Int::BoolView>*& tb, 00079 double m, double& d) const { 00080 switch (this->t) { 00081 case NT_CONST: 00082 Int::Limits::check(m*c,"MiniModel::LinExpr"); 00083 d += m*c; 00084 break; 00085 case NT_VAR_INT: 00086 Int::Limits::check(m*a,"MiniModel::LinExpr"); 00087 ti->a=static_cast<int>(m*a); ti->x=x_int; ti++; 00088 break; 00089 case NT_NONLIN: 00090 ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, NULL, icl); ti++; 00091 break; 00092 case NT_VAR_BOOL: 00093 Int::Limits::check(m*a,"MiniModel::LinExpr"); 00094 tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++; 00095 break; 00096 case NT_SUM_INT: 00097 for (int i=n_int; i--; ) { 00098 Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinExpr"); 00099 ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a); 00100 } 00101 ti += n_int; 00102 break; 00103 case NT_SUM_BOOL: 00104 for (int i=n_bool; i--; ) { 00105 Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinExpr"); 00106 tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a); 00107 } 00108 tb += n_bool; 00109 break; 00110 case NT_ADD: 00111 if (l == NULL) { 00112 Int::Limits::check(m*c,"MiniModel::LinExpr"); 00113 d += m*c; 00114 } else { 00115 l->fill(home,icl,ti,tb,m,d); 00116 } 00117 r->fill(home,icl,ti,tb,m,d); 00118 break; 00119 case NT_SUB: 00120 if (l == NULL) { 00121 Int::Limits::check(m*c,"MiniModel::LinExpr"); 00122 d += m*c; 00123 } else { 00124 l->fill(home,icl,ti,tb,m,d); 00125 } 00126 r->fill(home,icl,ti,tb,-m,d); 00127 break; 00128 case NT_MUL: 00129 Int::Limits::check(m*a,"MiniModel::LinExpr"); 00130 l->fill(home,icl,ti,tb,m*a,d); 00131 break; 00132 default: 00133 GECODE_NEVER; 00134 } 00135 } 00136 00137 00138 /* 00139 * Operators 00140 * 00141 */ 00142 LinExpr 00143 operator +(int c, const IntVar& x) { 00144 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)+x.val())) 00145 return LinExpr(static_cast<double>(c)+x.val()); 00146 else 00147 return LinExpr(x,LinExpr::NT_ADD,c); 00148 } 00149 LinExpr 00150 operator +(int c, const BoolVar& x) { 00151 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)+x.val())) 00152 return LinExpr(static_cast<double>(c)+x.val()); 00153 else 00154 return LinExpr(x,LinExpr::NT_ADD,c); 00155 } 00156 LinExpr 00157 operator +(int c, const LinExpr& e) { 00158 return LinExpr(e,LinExpr::NT_ADD,c); 00159 } 00160 LinExpr 00161 operator +(const IntVar& x, int c) { 00162 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)+x.val())) 00163 return LinExpr(static_cast<double>(c)+x.val()); 00164 else 00165 return LinExpr(x,LinExpr::NT_ADD,c); 00166 } 00167 LinExpr 00168 operator +(const BoolVar& x, int c) { 00169 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)+x.val())) 00170 return LinExpr(static_cast<double>(c)+x.val()); 00171 else 00172 return LinExpr(x,LinExpr::NT_ADD,c); 00173 } 00174 LinExpr 00175 operator +(const LinExpr& e, int c) { 00176 return LinExpr(e,LinExpr::NT_ADD,c); 00177 } 00178 LinExpr 00179 operator +(const IntVar& x, const IntVar& y) { 00180 if (x.assigned()) 00181 return x.val() + y; 00182 else if (y.assigned()) 00183 return x + y.val(); 00184 else 00185 return LinExpr(x,LinExpr::NT_ADD,y); 00186 } 00187 LinExpr 00188 operator +(const IntVar& x, const BoolVar& y) { 00189 if (x.assigned()) 00190 return x.val() + y; 00191 else if (y.assigned()) 00192 return x + y.val(); 00193 else 00194 return LinExpr(x,LinExpr::NT_ADD,y); 00195 } 00196 LinExpr 00197 operator +(const BoolVar& x, const IntVar& y) { 00198 if (x.assigned()) 00199 return x.val() + y; 00200 else if (y.assigned()) 00201 return x + y.val(); 00202 else 00203 return LinExpr(x,LinExpr::NT_ADD,y); 00204 } 00205 LinExpr 00206 operator +(const BoolVar& x, const BoolVar& y) { 00207 if (x.assigned()) 00208 return x.val() + y; 00209 else if (y.assigned()) 00210 return x + y.val(); 00211 else 00212 return LinExpr(x,LinExpr::NT_ADD,y); 00213 } 00214 LinExpr 00215 operator +(const IntVar& x, const LinExpr& e) { 00216 if (x.assigned()) 00217 return x.val() + e; 00218 else 00219 return LinExpr(x,LinExpr::NT_ADD,e); 00220 } 00221 LinExpr 00222 operator +(const BoolVar& x, const LinExpr& e) { 00223 if (x.assigned()) 00224 return x.val() + e; 00225 else 00226 return LinExpr(x,LinExpr::NT_ADD,e); 00227 } 00228 LinExpr 00229 operator +(const LinExpr& e, const IntVar& x) { 00230 if (x.assigned()) 00231 return e + x.val(); 00232 else 00233 return LinExpr(e,LinExpr::NT_ADD,x); 00234 } 00235 LinExpr 00236 operator +(const LinExpr& e, const BoolVar& x) { 00237 if (x.assigned()) 00238 return e + x.val(); 00239 else 00240 return LinExpr(e,LinExpr::NT_ADD,x); 00241 } 00242 LinExpr 00243 operator +(const LinExpr& e1, const LinExpr& e2) { 00244 return LinExpr(e1,LinExpr::NT_ADD,e2); 00245 } 00246 00247 LinExpr 00248 operator -(int c, const IntVar& x) { 00249 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)-x.val())) 00250 return LinExpr(static_cast<double>(c)-x.val()); 00251 else 00252 return LinExpr(x,LinExpr::NT_SUB,c); 00253 } 00254 LinExpr 00255 operator -(int c, const BoolVar& x) { 00256 if (x.assigned() && Int::Limits::valid(static_cast<double>(c)-x.val())) 00257 return LinExpr(static_cast<double>(c)-x.val()); 00258 else 00259 return LinExpr(x,LinExpr::NT_SUB,c); 00260 } 00261 LinExpr 00262 operator -(int c, const LinExpr& e) { 00263 return LinExpr(e,LinExpr::NT_SUB,c); 00264 } 00265 LinExpr 00266 operator -(const IntVar& x, int c) { 00267 if (x.assigned() && Int::Limits::valid(x.val()-static_cast<double>(c))) 00268 return LinExpr(x.val()-static_cast<double>(c)); 00269 else 00270 return LinExpr(x,LinExpr::NT_ADD,-c); 00271 } 00272 LinExpr 00273 operator -(const BoolVar& x, int c) { 00274 if (x.assigned() && Int::Limits::valid(x.val()-static_cast<double>(c))) 00275 return LinExpr(x.val()-static_cast<double>(c)); 00276 else 00277 return LinExpr(x,LinExpr::NT_ADD,-c); 00278 } 00279 LinExpr 00280 operator -(const LinExpr& e, int c) { 00281 return LinExpr(e,LinExpr::NT_ADD,-c); 00282 } 00283 LinExpr 00284 operator -(const IntVar& x, const IntVar& y) { 00285 if (x.assigned()) 00286 return x.val() - y; 00287 else if (y.assigned()) 00288 return x - y.val(); 00289 else 00290 return LinExpr(x,LinExpr::NT_SUB,y); 00291 } 00292 LinExpr 00293 operator -(const IntVar& x, const BoolVar& y) { 00294 if (x.assigned()) 00295 return x.val() - y; 00296 else if (y.assigned()) 00297 return x - y.val(); 00298 else 00299 return LinExpr(x,LinExpr::NT_SUB,y); 00300 } 00301 LinExpr 00302 operator -(const BoolVar& x, const IntVar& y) { 00303 if (x.assigned()) 00304 return x.val() - y; 00305 else if (y.assigned()) 00306 return x - y.val(); 00307 else 00308 return LinExpr(x,LinExpr::NT_SUB,y); 00309 } 00310 LinExpr 00311 operator -(const BoolVar& x, const BoolVar& y) { 00312 if (x.assigned()) 00313 return x.val() - y; 00314 else if (y.assigned()) 00315 return x - y.val(); 00316 else 00317 return LinExpr(x,LinExpr::NT_SUB,y); 00318 } 00319 LinExpr 00320 operator -(const IntVar& x, const LinExpr& e) { 00321 if (x.assigned()) 00322 return x.val() - e; 00323 else 00324 return LinExpr(x,LinExpr::NT_SUB,e); 00325 } 00326 LinExpr 00327 operator -(const BoolVar& x, const LinExpr& e) { 00328 if (x.assigned()) 00329 return x.val() - e; 00330 else 00331 return LinExpr(x,LinExpr::NT_SUB,e); 00332 } 00333 LinExpr 00334 operator -(const LinExpr& e, const IntVar& x) { 00335 if (x.assigned()) 00336 return e - x.val(); 00337 else 00338 return LinExpr(e,LinExpr::NT_SUB,x); 00339 } 00340 LinExpr 00341 operator -(const LinExpr& e, const BoolVar& x) { 00342 if (x.assigned()) 00343 return e - x.val(); 00344 else 00345 return LinExpr(e,LinExpr::NT_SUB,x); 00346 } 00347 LinExpr 00348 operator -(const LinExpr& e1, const LinExpr& e2) { 00349 return LinExpr(e1,LinExpr::NT_SUB,e2); 00350 } 00351 00352 LinExpr 00353 operator -(const IntVar& x) { 00354 if (x.assigned()) 00355 return LinExpr(-x.val()); 00356 else 00357 return LinExpr(x,LinExpr::NT_SUB,0); 00358 } 00359 LinExpr 00360 operator -(const BoolVar& x) { 00361 if (x.assigned()) 00362 return LinExpr(-x.val()); 00363 else 00364 return LinExpr(x,LinExpr::NT_SUB,0); 00365 } 00366 LinExpr 00367 operator -(const LinExpr& e) { 00368 return LinExpr(e,LinExpr::NT_SUB,0); 00369 } 00370 00371 LinExpr 00372 operator *(int a, const IntVar& x) { 00373 if (a == 0) 00374 return LinExpr(0.0); 00375 else if (x.assigned() && 00376 Int::Limits::valid(static_cast<double>(a)*x.val())) 00377 return LinExpr(static_cast<double>(a)*x.val()); 00378 else 00379 return LinExpr(x,a); 00380 } 00381 LinExpr 00382 operator *(int a, const BoolVar& x) { 00383 if (a == 0) 00384 return LinExpr(0.0); 00385 else if (x.assigned() && 00386 Int::Limits::valid(static_cast<double>(a)*x.val())) 00387 return LinExpr(static_cast<double>(a)*x.val()); 00388 else 00389 return LinExpr(x,a); 00390 } 00391 LinExpr 00392 operator *(const IntVar& x, int a) { 00393 if (a == 0) 00394 return LinExpr(0.0); 00395 else if (x.assigned() && 00396 Int::Limits::valid(static_cast<double>(a)*x.val())) 00397 return LinExpr(static_cast<double>(a)*x.val()); 00398 else 00399 return LinExpr(x,a); 00400 } 00401 LinExpr 00402 operator *(const BoolVar& x, int a) { 00403 if (a == 0) 00404 return LinExpr(0.0); 00405 else if (x.assigned() && 00406 Int::Limits::valid(static_cast<double>(a)*x.val())) 00407 return LinExpr(static_cast<double>(a)*x.val()); 00408 else 00409 return LinExpr(x,a); 00410 } 00411 LinExpr 00412 operator *(const LinExpr& e, int a) { 00413 if (a == 0) 00414 return LinExpr(0.0); 00415 else 00416 return LinExpr(a,e); 00417 } 00418 LinExpr 00419 operator *(int a, const LinExpr& e) { 00420 if (a == 0) 00421 return LinExpr(0.0); 00422 else 00423 return LinExpr(a,e); 00424 } 00425 00426 LinExpr 00427 sum(const IntVarArgs& x) { 00428 return LinExpr(x); 00429 } 00430 LinExpr 00431 sum(const IntArgs& a, const IntVarArgs& x) { 00432 return LinExpr(a,x); 00433 } 00434 LinExpr 00435 sum(const BoolVarArgs& x) { 00436 return LinExpr(x); 00437 } 00438 LinExpr 00439 sum(const IntArgs& a, const BoolVarArgs& x) { 00440 return LinExpr(a,x); 00441 } 00442 00443 00444 IntVar 00445 expr(Home home, const LinExpr& e, IntConLevel icl) { 00446 if (!home.failed()) 00447 return e.post(home,icl); 00448 IntVar x(home,Int::Limits::min,Int::Limits::max); 00449 return x; 00450 } 00451 00452 } 00453 00454 // STATISTICS: minimodel-any