Generated on Tue Apr 18 10:21:33 2017 for Gecode by doxygen 1.6.3

arithmetic.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, 2002
00008  *
00009  *  Last modified:
00010  *     $Date: 2017-03-23 15:08:48 +0100 (Thu, 23 Mar 2017) $ by $Author: schulte $
00011  *     $Revision: 15616 $
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/int/arithmetic.hh>
00039 
00040 namespace Gecode {
00041 
00042   void
00043   abs(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00044     using namespace Int;
00045     GECODE_POST;
00046     if (vbd(ipl) == IPL_DOM) {
00047       GECODE_ES_FAIL(Arithmetic::AbsDom<IntView>::post(home,x0,x1));
00048     } else {
00049       GECODE_ES_FAIL(Arithmetic::AbsBnd<IntView>::post(home,x0,x1));
00050     }
00051   }
00052 
00053 
00054   void
00055   max(Home home, IntVar x0, IntVar x1, IntVar x2,
00056       IntPropLevel ipl) {
00057     using namespace Int;
00058     GECODE_POST;
00059     if (vbd(ipl) == IPL_DOM) {
00060       GECODE_ES_FAIL(Arithmetic::MaxDom<IntView>::post(home,x0,x1,x2));
00061     } else {
00062       GECODE_ES_FAIL(Arithmetic::MaxBnd<IntView>::post(home,x0,x1,x2));
00063     }
00064   }
00065 
00066   void
00067   max(Home home, const IntVarArgs& x, IntVar y,
00068       IntPropLevel ipl) {
00069     using namespace Int;
00070     if (x.size() == 0)
00071       throw TooFewArguments("Int::max");
00072     GECODE_POST;
00073     ViewArray<IntView> xv(home,x);
00074     if (vbd(ipl) == IPL_DOM) {
00075       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<IntView>::post(home,xv,y));
00076     } else {
00077       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<IntView>::post(home,xv,y));
00078     }
00079   }
00080 
00081   void
00082   min(Home home, IntVar x0, IntVar x1, IntVar x2,
00083       IntPropLevel ipl) {
00084     using namespace Int;
00085     GECODE_POST;
00086     MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00087     if (vbd(ipl) == IPL_DOM) {
00088       GECODE_ES_FAIL(Arithmetic::MaxDom<MinusView>::post(home,m0,m1,m2));
00089     } else {
00090       GECODE_ES_FAIL(Arithmetic::MaxBnd<MinusView>::post(home,m0,m1,m2));
00091     }
00092   }
00093 
00094   void
00095   min(Home home, const IntVarArgs& x, IntVar y,
00096       IntPropLevel ipl) {
00097     using namespace Int;
00098     if (x.size() == 0)
00099       throw TooFewArguments("Int::min");
00100     GECODE_POST;
00101     ViewArray<MinusView> m(home,x.size());
00102     for (int i=x.size(); i--; )
00103       m[i] = MinusView(x[i]);
00104     MinusView my(y);
00105     if (vbd(ipl) == IPL_DOM) {
00106       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<MinusView>::post(home,m,my));
00107     } else {
00108       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<MinusView>::post(home,m,my));
00109     }
00110   }
00111 
00112 
00113   void
00114   argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00115          IntPropLevel) {
00116     using namespace Int;
00117     if (x.size() == 0)
00118       throw TooFewArguments("Int::argmax");
00119     if (x.same(home,y))
00120       throw ArgumentSame("Int::argmax");
00121     GECODE_POST;
00122     // Constrain y properly
00123     IntView yv(y);
00124     GECODE_ME_FAIL(yv.gq(home,0));
00125     GECODE_ME_FAIL(yv.le(home,x.size()));
00126     // Construct index view array
00127     IdxViewArray<IntView> ix(home,x.size());
00128     for (int i=x.size(); i--; ) {
00129       ix[i].idx=i; ix[i].view=x[i];
00130     }
00131     if (tiebreak)
00132         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,true>
00133                         ::post(home,ix,yv)));
00134     else
00135         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,false>
00136                         ::post(home,ix,yv)));
00137   }
00138 
00139   void
00140   argmax(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00141          IntPropLevel) {
00142     using namespace Int;
00143     Limits::nonnegative(o,"Int::argmax");
00144     if (x.size() == 0)
00145       throw TooFewArguments("Int::argmax");
00146     if (x.same(home,y))
00147       throw ArgumentSame("Int::argmax");
00148     GECODE_POST;
00149     // Constrain y properly
00150     OffsetView yv(y,-o);
00151     GECODE_ME_FAIL(yv.gq(home,0));
00152     GECODE_ME_FAIL(yv.le(home,x.size()));
00153     // Construct index view array
00154     IdxViewArray<IntView> ix(home,x.size());
00155     for (int i=x.size(); i--; ) {
00156       ix[i].idx=i; ix[i].view=x[i];
00157     }
00158     if (tiebreak)
00159         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,true>
00160                         ::post(home,ix,yv)));
00161     else
00162         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,false>
00163                         ::post(home,ix,yv)));
00164   }
00165 
00166   void
00167   argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00168          IntPropLevel) {
00169     using namespace Int;
00170     if (x.size() == 0)
00171       throw TooFewArguments("Int::argmin");
00172     if (x.same(home,y))
00173       throw ArgumentSame("Int::argmin");
00174     GECODE_POST;
00175     // Constrain y properly
00176     IntView yv(y);
00177     GECODE_ME_FAIL(yv.gq(home,0));
00178     GECODE_ME_FAIL(yv.le(home,x.size()));
00179     // Construct index view array
00180     IdxViewArray<MinusView> ix(home,x.size());
00181     for (int i=x.size(); i--; ) {
00182       ix[i].idx=i; ix[i].view=MinusView(x[i]);
00183     }
00184     if (tiebreak)
00185         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true>
00186                         ::post(home,ix,yv)));
00187     else
00188         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false>
00189                         ::post(home,ix,yv)));
00190   }
00191 
00192   void
00193   argmin(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00194          IntPropLevel) {
00195     using namespace Int;
00196     Limits::nonnegative(o,"Int::argmin");
00197     if (x.size() == 0)
00198       throw TooFewArguments("Int::argmin");
00199     if (x.same(home,y))
00200       throw ArgumentSame("Int::argmin");
00201     GECODE_POST;
00202     // Constrain y properly
00203     OffsetView yv(y,-o);
00204     GECODE_ME_FAIL(yv.gq(home,0));
00205     GECODE_ME_FAIL(yv.le(home,x.size()));
00206     // Construct index view array
00207     IdxViewArray<MinusView> ix(home,x.size());
00208     for (int i=x.size(); i--; ) {
00209       ix[i].idx=i; ix[i].view=MinusView(x[i]);
00210     }
00211     if (tiebreak)
00212         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,true>
00213                         ::post(home,ix,yv)));
00214     else
00215         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,false>
00216                         ::post(home,ix,yv)));
00217   }
00218 
00219 
00220   void
00221   mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00222        IntPropLevel ipl) {
00223     using namespace Int;
00224     GECODE_POST;
00225     if (vbd(ipl) == IPL_DOM) {
00226       GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00227     } else {
00228       GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00229     }
00230   }
00231 
00232 
00233   void
00234   divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00235          IntPropLevel) {
00236     using namespace Int;
00237     GECODE_POST;
00238 
00239     IntVar prod(home, Int::Limits::min, Int::Limits::max);
00240     GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00241     Linear::Term<IntView> t[3];
00242     t[0].a = 1; t[0].x = prod;
00243     t[1].a = 1; t[1].x = x3;
00244     int min, max;
00245     Linear::estimate(t,2,0,min,max);
00246     IntView x0v(x0);
00247     GECODE_ME_FAIL(x0v.gq(home,min));
00248     GECODE_ME_FAIL(x0v.lq(home,max));
00249     t[2].a=-1; t[2].x=x0;
00250     Linear::post(home,t,3,IRT_EQ,0,IPL_BND);
00251     if (home.failed()) return;
00252     IntView x1v(x1);
00253     GECODE_ES_FAIL(
00254       Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00255   }
00256 
00257   void
00258   div(Home home, IntVar x0, IntVar x1, IntVar x2,
00259       IntPropLevel) {
00260     using namespace Int;
00261     GECODE_POST;
00262     GECODE_ES_FAIL(
00263       (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00264   }
00265 
00266   void
00267   mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00268       IntPropLevel ipl) {
00269     using namespace Int;
00270     GECODE_POST;
00271     IntVar _div(home, Int::Limits::min, Int::Limits::max);
00272     divmod(home, x0, x1, _div, x2, ipl);
00273   }
00274 
00275   void
00276   sqr(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00277     using namespace Int;
00278     GECODE_POST;
00279     Arithmetic::SqrOps ops;
00280     if (vbd(ipl) == IPL_DOM) {
00281       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00282                      ::post(home,x0,x1,ops));
00283     } else {
00284       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00285                      ::post(home,x0,x1,ops));
00286     }
00287   }
00288 
00289   void
00290   sqrt(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00291     using namespace Int;
00292     GECODE_POST;
00293     Arithmetic::SqrOps ops;
00294     if (vbd(ipl) == IPL_DOM) {
00295       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00296                      ::post(home,x0,x1,ops));
00297     } else {
00298       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00299                      ::post(home,x0,x1,ops));
00300     }
00301   }
00302 
00303   void
00304   pow(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00305     using namespace Int;
00306     Limits::nonnegative(n,"Int::pow");
00307     GECODE_POST;
00308     if (n == 2) {
00309       sqr(home, x0, x1, ipl);
00310       return;
00311     }
00312     Arithmetic::PowOps ops(n);
00313     if (vbd(ipl) == IPL_DOM) {
00314       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00315                      ::post(home,x0,x1,ops));
00316     } else {
00317       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00318                      ::post(home,x0,x1,ops));
00319     }
00320   }
00321 
00322   void
00323   nroot(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00324     using namespace Int;
00325     Limits::positive(n,"Int::nroot");
00326     GECODE_POST;
00327     if (n == 2) {
00328       sqrt(home, x0, x1, ipl);
00329       return;
00330     }
00331     Arithmetic::PowOps ops(n);
00332     if (vbd(ipl) == IPL_DOM) {
00333       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00334                      ::post(home,x0,x1,ops));
00335     } else {
00336       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00337                      ::post(home,x0,x1,ops));
00338     }
00339   }
00340 
00341 }
00342 
00343 // STATISTICS: int-post