Generated on Fri Oct 19 11:24:51 2018 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  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00031  *
00032  */
00033 
00034 #include <gecode/int/arithmetic.hh>
00035 
00036 namespace Gecode {
00037 
00038   void
00039   abs(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00040     using namespace Int;
00041     GECODE_POST;
00042     if (vbd(ipl) == IPL_DOM) {
00043       GECODE_ES_FAIL(Arithmetic::AbsDom<IntView>::post(home,x0,x1));
00044     } else {
00045       GECODE_ES_FAIL(Arithmetic::AbsBnd<IntView>::post(home,x0,x1));
00046     }
00047   }
00048 
00049 
00050   void
00051   max(Home home, IntVar x0, IntVar x1, IntVar x2,
00052       IntPropLevel ipl) {
00053     using namespace Int;
00054     GECODE_POST;
00055     if (vbd(ipl) == IPL_DOM) {
00056       GECODE_ES_FAIL(Arithmetic::MaxDom<IntView>::post(home,x0,x1,x2));
00057     } else {
00058       GECODE_ES_FAIL(Arithmetic::MaxBnd<IntView>::post(home,x0,x1,x2));
00059     }
00060   }
00061 
00062   void
00063   max(Home home, const IntVarArgs& x, IntVar y,
00064       IntPropLevel ipl) {
00065     using namespace Int;
00066     if (x.size() == 0)
00067       throw TooFewArguments("Int::max");
00068     GECODE_POST;
00069     ViewArray<IntView> xv(home,x);
00070     if (vbd(ipl) == IPL_DOM) {
00071       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<IntView>::post(home,xv,y));
00072     } else {
00073       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<IntView>::post(home,xv,y));
00074     }
00075   }
00076 
00077   void
00078   min(Home home, IntVar x0, IntVar x1, IntVar x2,
00079       IntPropLevel ipl) {
00080     using namespace Int;
00081     GECODE_POST;
00082     MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00083     if (vbd(ipl) == IPL_DOM) {
00084       GECODE_ES_FAIL(Arithmetic::MaxDom<MinusView>::post(home,m0,m1,m2));
00085     } else {
00086       GECODE_ES_FAIL(Arithmetic::MaxBnd<MinusView>::post(home,m0,m1,m2));
00087     }
00088   }
00089 
00090   void
00091   min(Home home, const IntVarArgs& x, IntVar y,
00092       IntPropLevel ipl) {
00093     using namespace Int;
00094     if (x.size() == 0)
00095       throw TooFewArguments("Int::min");
00096     GECODE_POST;
00097     ViewArray<MinusView> m(home,x.size());
00098     for (int i=0; i<x.size(); i++)
00099       m[i] = MinusView(x[i]);
00100     MinusView my(y);
00101     if (vbd(ipl) == IPL_DOM) {
00102       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<MinusView>::post(home,m,my));
00103     } else {
00104       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<MinusView>::post(home,m,my));
00105     }
00106   }
00107 
00108 
00109   void
00110   argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00111          IntPropLevel) {
00112     using namespace Int;
00113     if (x.size() == 0)
00114       throw TooFewArguments("Int::argmax");
00115     if (same(x,y))
00116       throw ArgumentSame("Int::argmax");
00117     GECODE_POST;
00118     // Constrain y properly
00119     IntView yv(y);
00120     GECODE_ME_FAIL(yv.gq(home,0));
00121     GECODE_ME_FAIL(yv.le(home,x.size()));
00122     // Construct index view array
00123     IdxViewArray<IntView> ix(home,x.size());
00124     for (int i=0; i<x.size(); i++) {
00125       ix[i].idx=i; ix[i].view=x[i];
00126     }
00127     if (tiebreak)
00128         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,true>
00129                         ::post(home,ix,yv)));
00130     else
00131         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,false>
00132                         ::post(home,ix,yv)));
00133   }
00134 
00135   void
00136   argmax(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00137          IntPropLevel) {
00138     using namespace Int;
00139     Limits::nonnegative(o,"Int::argmax");
00140     if (x.size() == 0)
00141       throw TooFewArguments("Int::argmax");
00142     if (same(x,y))
00143       throw ArgumentSame("Int::argmax");
00144     GECODE_POST;
00145     // Constrain y properly
00146     OffsetView yv(y,-o);
00147     GECODE_ME_FAIL(yv.gq(home,0));
00148     GECODE_ME_FAIL(yv.le(home,x.size()));
00149     // Construct index view array
00150     IdxViewArray<IntView> ix(home,x.size());
00151     for (int i=0; i<x.size(); i++) {
00152       ix[i].idx=i; ix[i].view=x[i];
00153     }
00154     if (tiebreak)
00155         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,true>
00156                         ::post(home,ix,yv)));
00157     else
00158         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,false>
00159                         ::post(home,ix,yv)));
00160   }
00161 
00162   void
00163   argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00164          IntPropLevel) {
00165     using namespace Int;
00166     if (x.size() == 0)
00167       throw TooFewArguments("Int::argmin");
00168     if (same(x,y))
00169       throw ArgumentSame("Int::argmin");
00170     GECODE_POST;
00171     // Constrain y properly
00172     IntView yv(y);
00173     GECODE_ME_FAIL(yv.gq(home,0));
00174     GECODE_ME_FAIL(yv.le(home,x.size()));
00175     // Construct index view array
00176     IdxViewArray<MinusView> ix(home,x.size());
00177     for (int i=0; i<x.size(); i++) {
00178       ix[i].idx=i; ix[i].view=MinusView(x[i]);
00179     }
00180     if (tiebreak)
00181         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true>
00182                         ::post(home,ix,yv)));
00183     else
00184         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false>
00185                         ::post(home,ix,yv)));
00186   }
00187 
00188   void
00189   argmin(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00190          IntPropLevel) {
00191     using namespace Int;
00192     Limits::nonnegative(o,"Int::argmin");
00193     if (x.size() == 0)
00194       throw TooFewArguments("Int::argmin");
00195     if (same(x,y))
00196       throw ArgumentSame("Int::argmin");
00197     GECODE_POST;
00198     // Constrain y properly
00199     OffsetView yv(y,-o);
00200     GECODE_ME_FAIL(yv.gq(home,0));
00201     GECODE_ME_FAIL(yv.le(home,x.size()));
00202     // Construct index view array
00203     IdxViewArray<MinusView> ix(home,x.size());
00204     for (int i=0; i<x.size(); i++) {
00205       ix[i].idx=i; ix[i].view=MinusView(x[i]);
00206     }
00207     if (tiebreak)
00208         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,true>
00209                         ::post(home,ix,yv)));
00210     else
00211         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,false>
00212                         ::post(home,ix,yv)));
00213   }
00214 
00215 
00216   void
00217   mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00218        IntPropLevel ipl) {
00219     using namespace Int;
00220     GECODE_POST;
00221     if (vbd(ipl) == IPL_DOM) {
00222       GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00223     } else {
00224       GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00225     }
00226   }
00227 
00228 
00229   void
00230   divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00231          IntPropLevel) {
00232     using namespace Int;
00233     GECODE_POST;
00234 
00235     IntVar prod(home, Int::Limits::min, Int::Limits::max);
00236     GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00237     Linear::Term<IntView> t[3];
00238     t[0].a = 1; t[0].x = prod;
00239     t[1].a = 1; t[1].x = x3;
00240     int min, max;
00241     Linear::estimate(t,2,0,min,max);
00242     IntView x0v(x0);
00243     GECODE_ME_FAIL(x0v.gq(home,min));
00244     GECODE_ME_FAIL(x0v.lq(home,max));
00245     t[2].a=-1; t[2].x=x0;
00246     Linear::post(home,t,3,IRT_EQ,0,IPL_BND);
00247     if (home.failed()) return;
00248     IntView x1v(x1);
00249     GECODE_ES_FAIL(
00250       Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00251   }
00252 
00253   void
00254   div(Home home, IntVar x0, IntVar x1, IntVar x2,
00255       IntPropLevel) {
00256     using namespace Int;
00257     GECODE_POST;
00258     GECODE_ES_FAIL(
00259       (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00260   }
00261 
00262   void
00263   mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00264       IntPropLevel ipl) {
00265     using namespace Int;
00266     GECODE_POST;
00267     IntVar _div(home, Int::Limits::min, Int::Limits::max);
00268     divmod(home, x0, x1, _div, x2, ipl);
00269   }
00270 
00271   void
00272   sqr(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00273     using namespace Int;
00274     GECODE_POST;
00275     Arithmetic::SqrOps ops;
00276     if (vbd(ipl) == IPL_DOM) {
00277       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00278                      ::post(home,x0,x1,ops));
00279     } else {
00280       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00281                      ::post(home,x0,x1,ops));
00282     }
00283   }
00284 
00285   void
00286   sqrt(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00287     using namespace Int;
00288     GECODE_POST;
00289     Arithmetic::SqrOps ops;
00290     if (vbd(ipl) == IPL_DOM) {
00291       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00292                      ::post(home,x0,x1,ops));
00293     } else {
00294       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00295                      ::post(home,x0,x1,ops));
00296     }
00297   }
00298 
00299   void
00300   pow(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00301     using namespace Int;
00302     Limits::nonnegative(n,"Int::pow");
00303     GECODE_POST;
00304     if (n == 2) {
00305       sqr(home, x0, x1, ipl);
00306       return;
00307     }
00308     Arithmetic::PowOps ops(n);
00309     if (vbd(ipl) == IPL_DOM) {
00310       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00311                      ::post(home,x0,x1,ops));
00312     } else {
00313       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00314                      ::post(home,x0,x1,ops));
00315     }
00316   }
00317 
00318   void
00319   nroot(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00320     using namespace Int;
00321     Limits::positive(n,"Int::nroot");
00322     GECODE_POST;
00323     if (n == 2) {
00324       sqrt(home, x0, x1, ipl);
00325       return;
00326     }
00327     Arithmetic::PowOps ops(n);
00328     if (vbd(ipl) == IPL_DOM) {
00329       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00330                      ::post(home,x0,x1,ops));
00331     } else {
00332       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00333                      ::post(home,x0,x1,ops));
00334     }
00335   }
00336 
00337 }
00338 
00339 // STATISTICS: int-post