Generated on Wed Nov 5 2014 05:18:17 for Gecode by doxygen 1.7.6.1
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: 2012-09-03 17:08:20 +0200 (Mon, 03 Sep 2012) $ by $Author: schulte $
00011  *     $Revision: 13038 $
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, IntConLevel icl) {
00044     using namespace Int;
00045     if (home.failed()) return;
00046     if (icl == ICL_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       IntConLevel icl) {
00057     using namespace Int;
00058     if (home.failed()) return;
00059     if (icl == ICL_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       IntConLevel icl) {
00069     using namespace Int;
00070     if (x.size() == 0)
00071       throw TooFewArguments("Int::max");
00072     if (home.failed()) return;
00073     ViewArray<IntView> xv(home,x);
00074     if (icl == ICL_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       IntConLevel icl) {
00084     using namespace Int;
00085     if (home.failed()) return;
00086     MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00087     if (icl == ICL_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       IntConLevel icl) {
00097     using namespace Int;
00098     if (x.size() == 0)
00099       throw TooFewArguments("Int::min");
00100     if (home.failed()) return;
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 (icl == ICL_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   mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00115        IntConLevel icl) {
00116     using namespace Int;
00117     if (home.failed()) return;
00118     if (icl == ICL_DOM) {
00119       GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00120     } else {
00121       GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00122     }
00123   }
00124 
00125 
00126   void
00127   divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00128          IntConLevel) {
00129     using namespace Int;
00130     if (home.failed()) return;
00131 
00132     IntVar prod(home, Int::Limits::min, Int::Limits::max);
00133     GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00134     Linear::Term<IntView> t[3];
00135     t[0].a = 1; t[0].x = prod;
00136     t[1].a = 1; t[1].x = x3;
00137     int min, max;
00138     Linear::estimate(t,2,0,min,max);
00139     IntView x0v(x0);
00140     GECODE_ME_FAIL(x0v.gq(home,min));
00141     GECODE_ME_FAIL(x0v.lq(home,max));
00142     t[2].a=-1; t[2].x=x0;
00143     Linear::post(home,t,3,IRT_EQ,0);
00144     if (home.failed()) return;
00145     IntView x1v(x1);
00146     GECODE_ES_FAIL(
00147       Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00148   }
00149 
00150   void
00151   div(Home home, IntVar x0, IntVar x1, IntVar x2,
00152       IntConLevel) {
00153     using namespace Int;
00154     if (home.failed()) return;
00155     GECODE_ES_FAIL(
00156       (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00157   }
00158 
00159   void
00160   mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00161       IntConLevel icl) {
00162     using namespace Int;
00163     if (home.failed()) return;
00164     IntVar _div(home, Int::Limits::min, Int::Limits::max);
00165     divmod(home, x0, x1, _div, x2, icl);
00166   }
00167 
00168   void
00169   sqr(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00170     using namespace Int;
00171     if (home.failed()) return;
00172     Arithmetic::SqrOps ops;
00173     if (icl == ICL_DOM) {
00174       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00175                      ::post(home,x0,x1,ops));
00176     } else {
00177       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00178                      ::post(home,x0,x1,ops));
00179     }
00180   }
00181 
00182   void
00183   sqrt(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00184     using namespace Int;
00185     if (home.failed()) return;
00186     Arithmetic::SqrOps ops;
00187     if (icl == ICL_DOM) {
00188       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00189                      ::post(home,x0,x1,ops));
00190     } else {
00191       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00192                      ::post(home,x0,x1,ops));
00193     }
00194   }
00195 
00196   void
00197   pow(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00198     using namespace Int;
00199     Limits::nonnegative(n,"Int::pow");
00200     if (home.failed()) return;
00201     if (n == 2) {
00202       sqr(home, x0, x1, icl);
00203       return;
00204     }
00205     Arithmetic::PowOps ops(n);
00206     if (icl == ICL_DOM) {
00207       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00208                      ::post(home,x0,x1,ops));
00209     } else {
00210       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00211                      ::post(home,x0,x1,ops));
00212     }
00213   }
00214 
00215   void
00216   nroot(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00217     using namespace Int;
00218     Limits::positive(n,"Int::nroot");
00219     if (home.failed()) return;
00220     if (n == 2) {
00221       sqrt(home, x0, x1, icl);
00222       return;
00223     }
00224     Arithmetic::PowOps ops(n);
00225     if (icl == ICL_DOM) {
00226       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00227                      ::post(home,x0,x1,ops));
00228     } else {
00229       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00230                      ::post(home,x0,x1,ops));
00231     }
00232   }
00233 
00234 }
00235 
00236 // STATISTICS: int-post