Generated on Tue Jul 27 2010 21:59:17 for Gecode by doxygen 1.7.1

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