Generated on Fri Mar 20 15:55:56 2015 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, 2005
00008  *
00009  *  Last modified:
00010  *     $Date: 2015-01-16 14:10:48 +0100 (Fri, 16 Jan 2015) $ by $Author: schulte $
00011  *     $Revision: 14362 $
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 "test/int.hh"
00039 
00040 #include <cmath>
00041 #include <algorithm>
00042 
00043 #include <gecode/minimodel.hh>
00044 
00045 namespace Test { namespace Int {
00046 
00048    namespace Arithmetic {
00049 
00055 
00056      class MultXYZ : public Test {
00057      public:
00059        MultXYZ(const std::string& s, const Gecode::IntSet& d,
00060                Gecode::IntConLevel icl)
00061          : Test("Arithmetic::Mult::XYZ::"+str(icl)+"::"+s,3,d,false,icl) {}
00063        virtual bool solution(const Assignment& x) const {
00064          double d0 = static_cast<double>(x[0]);
00065          double d1 = static_cast<double>(x[1]);
00066          double d2 = static_cast<double>(x[2]);
00067          return d0*d1 == d2;
00068        }
00070        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00071          Gecode::mult(home, x[0], x[1], x[2], icl);
00072        }
00073      };
00074 
00076      class MultXXY : public Test {
00077      public:
00079        MultXXY(const std::string& s, const Gecode::IntSet& d,
00080                Gecode::IntConLevel icl)
00081          : Test("Arithmetic::Mult::XXY::"+str(icl)+"::"+s,2,d,false,icl) {}
00083        virtual bool solution(const Assignment& x) const {
00084          double d0 = static_cast<double>(x[0]);
00085          double d1 = static_cast<double>(x[0]);
00086          double d2 = static_cast<double>(x[1]);
00087          return d0*d1 == d2;
00088        }
00090        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00091          Gecode::mult(home, x[0], x[0], x[1], icl);
00092        }
00093      };
00094 
00096      class MultXYX : public Test {
00097      public:
00099        MultXYX(const std::string& s, const Gecode::IntSet& d,
00100                Gecode::IntConLevel icl)
00101          : Test("Arithmetic::Mult::XYX::"+str(icl)+"::"+s,2,d,false,icl) {}
00103        virtual bool solution(const Assignment& x) const {
00104          double d0 = static_cast<double>(x[0]);
00105          double d1 = static_cast<double>(x[1]);
00106          double d2 = static_cast<double>(x[0]);
00107          return d0*d1 == d2;
00108        }
00110        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00111          Gecode::mult(home, x[0], x[1], x[0], icl);
00112        }
00113      };
00114 
00116      class MultXYY : public Test {
00117      public:
00119        MultXYY(const std::string& s, const Gecode::IntSet& d,
00120                Gecode::IntConLevel icl)
00121          : Test("Arithmetic::Mult::XYY::"+str(icl)+"::"+s,2,d,false,icl) {}
00123        virtual bool solution(const Assignment& x) const {
00124          double d0 = static_cast<double>(x[0]);
00125          double d1 = static_cast<double>(x[1]);
00126          double d2 = static_cast<double>(x[1]);
00127          return d0*d1 == d2;
00128        }
00130        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00131          Gecode::mult(home, x[0], x[1], x[1], icl);
00132        }
00133      };
00134 
00136      class MultXXX : public Test {
00137      public:
00139        MultXXX(const std::string& s, const Gecode::IntSet& d,
00140                Gecode::IntConLevel icl)
00141          : Test("Arithmetic::Mult::XXX::"+str(icl)+"::"+s,1,d,false,icl) {}
00143        virtual bool solution(const Assignment& x) const {
00144          double d0 = static_cast<double>(x[0]);
00145          double d1 = static_cast<double>(x[0]);
00146          double d2 = static_cast<double>(x[0]);
00147          return d0*d1 == d2;
00148        }
00150        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00151          Gecode::mult(home, x[0], x[0], x[0], icl);
00152        }
00153      };
00154 
00156      class SqrXY : public Test {
00157      public:
00159        SqrXY(const std::string& s, const Gecode::IntSet& d,
00160              Gecode::IntConLevel icl)
00161          : Test("Arithmetic::Sqr::XY::"+str(icl)+"::"+s,2,d,false,icl) {}
00163        virtual bool solution(const Assignment& x) const {
00164          double d0 = static_cast<double>(x[0]);
00165          double d1 = static_cast<double>(x[1]);
00166          return d0*d0 == d1;
00167        }
00169        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00170          Gecode::sqr(home, x[0], x[1], icl);
00171        }
00172      };
00173      
00175      class SqrXX : public Test {
00176      public:
00178        SqrXX(const std::string& s, const Gecode::IntSet& d,
00179              Gecode::IntConLevel icl)
00180          : Test("Arithmetic::Sqr::XX::"+str(icl)+"::"+s,1,d,false,icl) {}
00182        virtual bool solution(const Assignment& x) const {
00183          double d0 = static_cast<double>(x[0]);
00184          return d0*d0 == d0;
00185        }
00187        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00188          Gecode::sqr(home, x[0], x[0], icl);
00189        }
00190      };
00191 
00193      class SqrtXY : public Test {
00194      public:
00196        SqrtXY(const std::string& s, const Gecode::IntSet& d,
00197               Gecode::IntConLevel icl)
00198          : Test("Arithmetic::Sqrt::XY::"+str(icl)+"::"+s,2,d,false,icl) {}
00200        virtual bool solution(const Assignment& x) const {
00201          double d0 = static_cast<double>(x[0]);
00202          double d1 = static_cast<double>(x[1]);
00203          return (d0 >= 0) && (d0 >= d1*d1) && (d0 < (d1+1)*(d1+1));
00204        }
00206        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00207          Gecode::sqrt(home, x[0], x[1], icl);
00208        }
00209      };
00210 
00212      class SqrtXX : public Test {
00213      public:
00215        SqrtXX(const std::string& s, const Gecode::IntSet& d,
00216               Gecode::IntConLevel icl)
00217          : Test("Arithmetic::Sqrt::XX::"+str(icl)+"::"+s,1,d,false,icl) {}
00219        virtual bool solution(const Assignment& x) const {
00220          double d0 = static_cast<double>(x[0]);
00221          return (d0 >= 0) && (d0 >= d0*d0) && (d0 < (d0+1)*(d0+1));
00222        }
00224        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00225          Gecode::sqrt(home, x[0], x[0], icl);
00226        }
00227      };
00228 
00230      class PowXY : public Test {
00231      protected:
00233        int n;
00234      public:
00236        PowXY(const std::string& s, int n0, const Gecode::IntSet& d,
00237              Gecode::IntConLevel icl)
00238          : Test("Arithmetic::Pow::XY::"+str(n0)+"::"+str(icl)+"::"+s,
00239                 2,d,false,icl), n(n0) {}
00241        virtual bool solution(const Assignment& x) const {
00242          long long int p = 1;
00243          for (int i=0; i<n; i++) {
00244            p *= x[0];
00245            if ((p < Gecode::Int::Limits::min) || 
00246                (p > Gecode::Int::Limits::max))
00247              return false;
00248          }
00249          return p == x[1];
00250        }
00252        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00253          using namespace Gecode;
00254          if (n > 4)
00255            pow(home, x[0], n, x[1], icl);
00256          else
00257            rel(home, expr(home, pow(x[0],n), icl), IRT_EQ, x[1], icl);
00258        }
00259      };
00260 
00262      class PowXX : public Test {
00263      protected:
00265        int n;
00266      public:
00268        PowXX(const std::string& s, int n0, const Gecode::IntSet& d,
00269              Gecode::IntConLevel icl)
00270          : Test("Arithmetic::Pow::XX::"+str(n0)+"::"+str(icl)+"::"+s,
00271                 1,d,false,icl), n(n0) {}
00273        virtual bool solution(const Assignment& x) const {
00274          long long int p = 1;
00275          for (int i=0; i<n; i++) {
00276            p *= x[0];
00277            if ((p < Gecode::Int::Limits::min) || 
00278                (p > Gecode::Int::Limits::max))
00279              return false;
00280          }
00281          return p == x[0];
00282        }
00284        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00285          Gecode::pow(home, x[0], n, x[0], icl);
00286        }
00287      };
00288 
00289      bool powgr(int n, long long int r, int x) {
00290        assert(r >= 0);
00291        long long int y = r;
00292        long long int p = 1;
00293        do {
00294          p *= y; n--;
00295          if (p > x)
00296            return true;
00297        } while (n > 0);
00298        return false;
00299      }
00300 
00301      int fnroot(int n, int x) {
00302        if (x < 2)
00303          return x;
00304        /*
00305         * We look for l such that: l^n <= x < (l+1)^n
00306         */
00307        long long int l = 1;
00308        long long int u = x;
00309        do {
00310          long long int m = (l + u) >> 1;
00311          if (powgr(n,m,x)) u=m; else l=m;
00312        } while (l+1 < u);
00313        return static_cast<int>(l);
00314      }
00315 
00316      bool powle(int n, long long int r, int x) {
00317        assert(r >= 0);
00318        long long int y = r;
00319        long long int p = 1;
00320        do {
00321          p *= y; n--;
00322          if (p >= x)
00323            return false;
00324        } while (n > 0);
00325        assert(y < x);
00326        return true;
00327      }
00328 
00329      int cnroot(int n, int x) {
00330        if (x < 2)
00331          return x;
00332        /*
00333         * We look for u such that: (u-1)^n < x <= u^n
00334         */
00335        long long int l = 1;
00336        long long int u = x;
00337        do {
00338          long long int m = (l + u) >> 1;
00339          if (powle(n,m,x)) l=m; else u=m;
00340        } while (l+1 < u);
00341        return static_cast<int>(u);
00342      }
00343 
00345      class NrootXY : public Test {
00346      protected:
00348        int n;
00350      public:
00352        NrootXY(const std::string& s, int n0, const Gecode::IntSet& d,
00353              Gecode::IntConLevel icl)
00354          : Test("Arithmetic::Nroot::XY::"+str(n0)+"::"+str(icl)+"::"+s,
00355                 2,d,false,icl), n(n0) {}
00357        virtual bool solution(const Assignment& x) const {
00358          if (n == 1)
00359            return x[0] == x[1];
00360          if ((n % 2 == 0) && ((x[0] < 0) || (x[1] < 0)))
00361            return false;
00362          int r = (x[0] < 0) ? -cnroot(n,-x[0]) : fnroot(n,x[0]);
00363          return r == x[1]; 
00364        }
00366        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00367          using namespace Gecode;
00368          if (n > 4)
00369            nroot(home, x[0], n, x[1], icl);
00370          else
00371            rel(home, expr(home, nroot(x[0],n), icl), IRT_EQ, x[1], icl);
00372        }
00373      };
00374 
00376      class NrootXX : public Test {
00377      protected:
00379        int n;
00380      public:
00382        NrootXX(const std::string& s, int n0, const Gecode::IntSet& d,
00383                Gecode::IntConLevel icl)
00384          : Test("Arithmetic::Nroot::XX::"+str(n0)+"::"+str(icl)+"::"+s,
00385                 1,d,false,icl), n(n0) {}
00387        virtual bool solution(const Assignment& x) const {
00388          if (n == 1)
00389            return true;
00390          if (n % 2 == 0) {
00391            return (x[0] >= 0) && (x[0] <= 1);
00392          } else {
00393            return (x[0] >= -2) && (x[0] <= 1);
00394          }
00395        }
00397        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00398          Gecode::nroot(home, x[0], n, x[0], icl);
00399        }
00400      };
00401 
00403      class DivMod : public Test {
00404      private:
00406        static int abs(int a) { return a<0 ? -a:a; }
00408        static int sgn(int a) { return a<0 ? -1:1; }
00409      public:
00411        DivMod(const std::string& s, const Gecode::IntSet& d)
00412          : Test("Arithmetic::DivMod::"+s,4,d) {}
00414        virtual bool solution(const Assignment& x) const {
00415          return x[0] == x[1]*x[2]+x[3] &&
00416                 abs(x[3]) < abs(x[1]) &&
00417                 (x[3] == 0 || sgn(x[3]) == sgn(x[0]));
00418        }
00420        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00421          Gecode::divmod(home, x[0], x[1], x[2], x[3]);
00422        }
00423      };
00424 
00426      class Div : public Test {
00427      public:
00429        Div(const std::string& s, const Gecode::IntSet& d)
00430          : Test("Arithmetic::Div::"+s,3,d) {}
00432        virtual bool solution(const Assignment& x) const {
00433          if (x[1] == 0)
00434            return false;
00435          int divsign = (x[0] / x[1] < 0) ? -1 : 1;
00436          int divresult =
00437            divsign *
00438            static_cast<int>(floor(static_cast<double>(std::abs(x[0]))/
00439                                   static_cast<double>(std::abs(x[1]))));
00440          return x[2] == divresult;
00441        }
00443        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00444          Gecode::div(home, x[0], x[1], x[2]);
00445        }
00446      };
00447 
00449      class Mod : public Test {
00450      public:
00452        Mod(const std::string& s, const Gecode::IntSet& d)
00453          : Test("Arithmetic::Mod::"+s,3,d) {}
00455        virtual bool solution(const Assignment& x) const {
00456          if (x[1] == 0)
00457            return false;
00458          int divsign = (x[0] / x[1] < 0) ? -1 : 1;
00459          int divresult =
00460            divsign *
00461            static_cast<int>(floor(static_cast<double>(std::abs(x[0]))/
00462                                   static_cast<double>(std::abs(x[1]))));
00463          return x[0] == x[1]*divresult+x[2];
00464        }
00466        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00467          Gecode::mod(home, x[0], x[1], x[2]);
00468        }
00469      };
00470 
00472      class AbsXY : public Test {
00473      public:
00475        AbsXY(const std::string& s, const Gecode::IntSet& d,
00476              Gecode::IntConLevel icl)
00477          : Test("Arithmetic::Abs::XY::"+str(icl)+"::"+s,2,d,false,icl) {}
00479        virtual bool solution(const Assignment& x) const {
00480          double d0 = static_cast<double>(x[0]);
00481          double d1 = static_cast<double>(x[1]);
00482          return (d0<0 ? -d0 : d0) == d1;
00483        }
00485        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00486          Gecode::abs(home, x[0], x[1], icl);
00487        }
00488      };
00489 
00491      class AbsXX : public Test {
00492      public:
00494        AbsXX(const std::string& s, const Gecode::IntSet& d,
00495              Gecode::IntConLevel icl)
00496          : Test("Arithmetic::Abs::XX::"+str(icl)+"::"+s,1,d,false,icl) {}
00498        virtual bool solution(const Assignment& x) const {
00499          double d0 = static_cast<double>(x[0]);
00500          double d1 = static_cast<double>(x[0]);
00501          return (d0<0 ? -d0 : d0) == d1;
00502        }
00504        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00505          Gecode::abs(home, x[0], x[0], icl);
00506        }
00507      };
00508 
00510      class MinXYZ : public Test {
00511      public:
00513        MinXYZ(const std::string& s, const Gecode::IntSet& d,
00514               Gecode::IntConLevel icl)
00515          : Test("Arithmetic::Min::Bin::XYZ::"+str(icl)+"::"+s,3,d,false,icl) {}
00517        virtual bool solution(const Assignment& x) const {
00518          return std::min(x[0],x[1]) == x[2];
00519        }
00521        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00522          Gecode::min(home, x[0], x[1], x[2], icl);
00523        }
00524      };
00525 
00527      class MinXXY : public Test {
00528      public:
00530        MinXXY(const std::string& s, const Gecode::IntSet& d,
00531               Gecode::IntConLevel icl)
00532          : Test("Arithmetic::Min::Bin::XYX::"+str(icl)+"::"+s,2,d) {}
00534        virtual bool solution(const Assignment& x) const {
00535          return std::min(x[0],x[0]) == x[1];
00536        }
00538        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00539          Gecode::min(home, x[0], x[0], x[1], icl);
00540        }
00541      };
00542 
00544      class MinXYX : public Test {
00545      public:
00547        MinXYX(const std::string& s, const Gecode::IntSet& d,
00548               Gecode::IntConLevel icl)
00549          : Test("Arithmetic::Min::Bin::XYX::"+str(icl)+"::"+s,2,d) {}
00551        virtual bool solution(const Assignment& x) const {
00552          return std::min(x[0],x[1]) == x[0];
00553        }
00555        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00556          Gecode::min(home, x[0], x[1], x[0], icl);
00557        }
00558      };
00559 
00561      class MinXYY : public Test {
00562      public:
00564        MinXYY(const std::string& s, const Gecode::IntSet& d,
00565               Gecode::IntConLevel icl)
00566          : Test("Arithmetic::Min::Bin::XYY::"+str(icl)+"::"+s,2,d) {}
00568        virtual bool solution(const Assignment& x) const {
00569          return std::min(x[0],x[1]) == x[1];
00570        }
00572        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00573          Gecode::min(home, x[0], x[1], x[1], icl);
00574        }
00575      };
00576 
00578      class MinXXX : public Test {
00579      public:
00581        MinXXX(const std::string& s, const Gecode::IntSet& d,
00582               Gecode::IntConLevel icl)
00583          : Test("Arithmetic::Min::Bin::XXX::"+str(icl)+"::"+s,1,d) {}
00585        virtual bool solution(const Assignment& x) const {
00586          return std::min(x[0],x[0]) == x[0];
00587        }
00589        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00590          Gecode::min(home, x[0], x[0], x[0], icl);
00591        }
00592      };
00593 
00595      class MaxXYZ : public Test {
00596      public:
00598        MaxXYZ(const std::string& s, const Gecode::IntSet& d,
00599               Gecode::IntConLevel icl)
00600          : Test("Arithmetic::Max::Bin::XYZ::"+str(icl)+"::"+s,3,d) {
00601          contest = CTL_BOUNDS_Z;
00602        }
00604        virtual bool solution(const Assignment& x) const {
00605          return std::max(x[0],x[1]) == x[2];
00606        }
00608        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00609          Gecode::max(home, x[0], x[1], x[2], icl);
00610        }
00611      };
00612 
00614      class MaxXXY : public Test {
00615      public:
00617        MaxXXY(const std::string& s, const Gecode::IntSet& d,
00618               Gecode::IntConLevel icl)
00619          : Test("Arithmetic::Max::Bin::XXY::"+str(icl)+"::"+s,2,d) {}
00621        virtual bool solution(const Assignment& x) const {
00622          return std::max(x[0],x[0]) == x[1];
00623        }
00625        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00626          Gecode::max(home, x[0], x[0], x[1], icl);
00627        }
00628      };
00629 
00631      class MaxXYX : public Test {
00632      public:
00634        MaxXYX(const std::string& s, const Gecode::IntSet& d,
00635               Gecode::IntConLevel icl)
00636          : Test("Arithmetic::Max::Bin::XYX::"+str(icl)+"::"+s,2,d) {}
00638        virtual bool solution(const Assignment& x) const {
00639          return std::max(x[0],x[1]) == x[0];
00640        }
00642        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00643          Gecode::max(home, x[0], x[1], x[0], icl);
00644        }
00645      };
00646 
00648      class MaxXYY : public Test {
00649      public:
00651        MaxXYY(const std::string& s, const Gecode::IntSet& d,
00652               Gecode::IntConLevel icl)
00653          : Test("Arithmetic::Max::Bin::XYY::"+str(icl)+"::"+s,2,d) {}
00655        virtual bool solution(const Assignment& x) const {
00656          return std::max(x[0],x[1]) == x[1];
00657        }
00659        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00660          Gecode::max(home, x[0], x[1], x[1], icl);
00661        }
00662      };
00663 
00665      class MaxXXX : public Test {
00666      public:
00668        MaxXXX(const std::string& s, const Gecode::IntSet& d,
00669               Gecode::IntConLevel icl)
00670          : Test("Arithmetic::Max::Bin::XXX::"+str(icl)+"::"+s,1,d) {}
00672        virtual bool solution(const Assignment& x) const {
00673          return std::max(x[0],x[0]) == x[0];
00674        }
00676        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00677          Gecode::max(home, x[0], x[0], x[0], icl);
00678        }
00679      };
00680 
00682      class MinNary : public Test {
00683      public:
00685        MinNary(Gecode::IntConLevel icl)
00686          : Test("Arithmetic::Min::Nary::"+str(icl),4,-4,4,false,icl) {}
00688        virtual bool solution(const Assignment& x) const {
00689          return std::min(std::min(x[0],x[1]), x[2]) == x[3];
00690        }
00692        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00693          Gecode::IntVarArgs m(3);
00694          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00695          Gecode::min(home, m, x[3], icl);
00696        }
00697      };
00698 
00700      class MinNaryShared : public Test {
00701      public:
00703        MinNaryShared(Gecode::IntConLevel icl)
00704          : Test("Arithmetic::Min::Nary::Shared::"+str(icl),3,-4,4,false,icl) {}
00706        virtual bool solution(const Assignment& x) const {
00707          return std::min(std::min(x[0],x[1]), x[2]) == x[1];
00708        }
00710        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00711          Gecode::IntVarArgs m(3);
00712          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00713          Gecode::min(home, m, x[1], icl);
00714        }
00715      };
00716 
00718      class MaxNary : public Test {
00719      public:
00721        MaxNary(Gecode::IntConLevel icl)
00722          : Test("Arithmetic::Max::Nary::"+str(icl),4,-4,4,false,icl) {}
00724        virtual bool solution(const Assignment& x) const {
00725          return std::max(std::max(x[0],x[1]), x[2]) == x[3];
00726        }
00728        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00729          Gecode::IntVarArgs m(3);
00730          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00731          Gecode::max(home, m, x[3], icl);
00732        }
00733      };
00734 
00736      class MaxNaryShared : public Test {
00737      public:
00739        MaxNaryShared(Gecode::IntConLevel icl)
00740          : Test("Arithmetic::Max::Nary::Shared::"+str(icl),3,-4,4,false,icl) {}
00742        virtual bool solution(const Assignment& x) const {
00743          return std::max(std::max(x[0],x[1]), x[2]) == x[1];
00744        }
00746        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00747          Gecode::IntVarArgs m(3);
00748          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00749          Gecode::max(home, m, x[1], icl);
00750        }
00751      };
00752 
00754      class ArgMax : public Test {
00755      protected:
00757        bool tiebreak;
00758      public:
00760        ArgMax(int n, bool tb)
00761          : Test("Arithmetic::ArgMax::"+str(tb)+"::"+str(n),n+1,0,n+1,
00762                 false,tb ? Gecode::ICL_DEF : Gecode::ICL_DOM),
00763            tiebreak(tb) {}
00765        virtual bool solution(const Assignment& x) const {
00766          int n=x.size()-1;
00767          if ((x[n] < 0) || (x[n] >= n))
00768            return false;
00769          int m=x[0]; int p=0;
00770          for (int i=1; i<n; i++)
00771            if (x[i] > m) {
00772              p=i; m=x[i];
00773            }
00774          return tiebreak ? (p == x[n]) : (m == x[x[n]]);
00775        }
00777        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00778          int n=x.size()-1;
00779          Gecode::IntVarArgs m(n);
00780          for (int i=0; i<n; i++)
00781            m[i]=x[i];
00782          Gecode::argmax(home, m, x[n], tiebreak);
00783        }
00784      };
00785 
00787      class ArgMaxShared : public Test {
00788      protected:
00790        bool tiebreak;
00791      public:
00793        ArgMaxShared(int n, bool tb)
00794          : Test("Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00795                 false),
00796            tiebreak(tb)  {}
00798        virtual bool solution(const Assignment& x) const {
00799          int n=x.size()-1;
00800          if ((x[n] < 0) || (x[n] >= 2*n))
00801            return false;
00802          Gecode::IntArgs y(2*n);
00803          for (int i=0; i<n; i++)
00804            y[2*i+0]=y[2*i+1]=x[i];
00805          int m=y[0]; int p=0;
00806          for (int i=1; i<2*n; i++)
00807            if (y[i] > m) {
00808              p=i; m=y[i];
00809            }
00810          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00811        }
00813        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00814          int n=x.size()-1;
00815          Gecode::IntVarArgs m(2*n);
00816          for (int i=0; i<n; i++)
00817            m[2*i+0]=m[2*i+1]=x[i];
00818          Gecode::argmax(home, m, x[n], tiebreak);
00819        }
00820      };
00821 
00823      class ArgMin : public Test {
00824      protected:
00826        bool tiebreak;
00827      public:
00829        ArgMin(int n, bool tb)
00830          : Test("Arithmetic::ArgMin::"+str(tb)+"::"+str(n),n+1,0,n+1,
00831                 false,tb ? Gecode::ICL_DEF : Gecode::ICL_DOM),
00832            tiebreak(tb)  {}
00834        virtual bool solution(const Assignment& x) const {
00835          int n=x.size()-1;
00836          if ((x[n] < 0) || (x[n] >= n))
00837            return false;
00838          int m=x[0]; int p=0;
00839          for (int i=1; i<n; i++)
00840            if (x[i] < m) {
00841              p=i; m=x[i];
00842            }
00843          return tiebreak ? (p == x[n]) : (m == x[x[n]]);
00844        }
00846        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00847          int n=x.size()-1;
00848          Gecode::IntVarArgs m(n);
00849          for (int i=0; i<n; i++)
00850            m[i]=x[i];
00851          Gecode::argmin(home, m, x[n], tiebreak);
00852        }
00853      };
00854 
00856      class ArgMinShared : public Test {
00857      protected:
00859        bool tiebreak;
00860      public:
00862        ArgMinShared(int n, bool tb)
00863          : Test("Arithmetic::ArgMin::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00864                 false),
00865            tiebreak(tb) {}
00867        virtual bool solution(const Assignment& x) const {
00868          int n=x.size()-1;
00869          if ((x[n] < 0) || (x[n] >= 2*n))
00870            return false;
00871          Gecode::IntArgs y(2*n);
00872          for (int i=0; i<n; i++)
00873            y[2*i+0]=y[2*i+1]=x[i];
00874          int m=y[0]; int p=0;
00875          for (int i=1; i<2*n; i++)
00876            if (y[i] < m) {
00877              p=i; m=y[i];
00878            }
00879          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00880        }
00882        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00883          int n=x.size()-1;
00884          Gecode::IntVarArgs m(2*n);
00885          for (int i=0; i<n; i++)
00886            m[2*i+0]=m[2*i+1]=x[i];
00887          Gecode::argmin(home, m, x[n], tiebreak);
00888        }
00889      };
00890 
00891 
00892 
00894      class Create {
00895      public:
00897        Create(void) {
00898 
00899          const int va[7] = {
00900            Gecode::Int::Limits::min, Gecode::Int::Limits::min+1,
00901            -1,0,1,
00902            Gecode::Int::Limits::max-1, Gecode::Int::Limits::max
00903          };
00904          const int vb[9] = {
00905            static_cast<int>(-sqrt(static_cast<double>
00906                                   (-Gecode::Int::Limits::min))),
00907            -4,-2,-1,0,1,2,4,
00908            static_cast<int>(sqrt(static_cast<double>
00909                                  (Gecode::Int::Limits::max)))
00910          };
00911          
00912          Gecode::IntSet a(va,7);
00913          Gecode::IntSet b(vb,9);
00914          Gecode::IntSet c(-8,8);
00915          Gecode::IntSet d(-70,70);
00916 
00917          (void) new DivMod("A",a);
00918          (void) new DivMod("B",b);
00919          (void) new DivMod("C",c);
00920          
00921          (void) new Div("A",a);
00922          (void) new Div("B",b);
00923          (void) new Div("C",c);
00924          
00925          (void) new Mod("A",a);
00926          (void) new Mod("B",b);
00927          (void) new Mod("C",c);
00928 
00929 
00930          for (IntConLevels icls; icls(); ++icls) 
00931            if (icls.icl() != Gecode::ICL_VAL) {
00932              (void) new MultXYZ("A",a,icls.icl());
00933              (void) new MultXYZ("B",b,icls.icl());
00934              (void) new MultXYZ("C",c,icls.icl());
00935 
00936              (void) new MultXXY("A",a,icls.icl());
00937              (void) new MultXXY("B",b,icls.icl());
00938              (void) new MultXXY("C",c,icls.icl());
00939 
00940              (void) new MultXYX("A",a,icls.icl());
00941              (void) new MultXYX("B",b,icls.icl());
00942              (void) new MultXYX("C",c,icls.icl());
00943 
00944              (void) new MultXYY("A",a,icls.icl());
00945              (void) new MultXYY("B",b,icls.icl());
00946              (void) new MultXYY("C",c,icls.icl());
00947 
00948              (void) new MultXXX("A",a,icls.icl());
00949              (void) new MultXXX("B",b,icls.icl());
00950              (void) new MultXXX("C",c,icls.icl());
00951 
00952              (void) new SqrXY("A",a,icls.icl());
00953              (void) new SqrXY("B",b,icls.icl());
00954              (void) new SqrXY("C",c,icls.icl());
00955 
00956              (void) new SqrXX("A",a,icls.icl());
00957              (void) new SqrXX("B",b,icls.icl());
00958              (void) new SqrXX("C",c,icls.icl());
00959 
00960              for (int n=0; n<=6; n++) {
00961                (void) new PowXY("A",n,a,icls.icl());
00962                (void) new PowXY("B",n,b,icls.icl());
00963                (void) new PowXY("C",n,c,icls.icl());
00964                (void) new PowXY("D",n,d,icls.icl());
00965   
00966                (void) new PowXX("A",n,a,icls.icl());
00967                (void) new PowXX("B",n,b,icls.icl());
00968                (void) new PowXX("C",n,c,icls.icl());
00969                (void) new PowXX("D",n,d,icls.icl());
00970              }
00971 
00972              for (int n=1; n<=6; n++) {
00973                (void) new NrootXY("A",n,a,icls.icl());
00974                (void) new NrootXY("B",n,b,icls.icl());
00975                (void) new NrootXY("C",n,c,icls.icl());
00976                (void) new NrootXY("D",n,d,icls.icl());
00977   
00978                (void) new NrootXX("A",n,a,icls.icl());
00979                (void) new NrootXX("B",n,b,icls.icl());
00980                (void) new NrootXX("C",n,c,icls.icl());
00981                (void) new NrootXX("D",n,d,icls.icl());
00982              }
00983 
00984              for (int n=30; n<=34; n++) {
00985                (void) new PowXY("C",n,c,icls.icl());
00986                (void) new PowXX("C",n,c,icls.icl());
00987                (void) new NrootXY("C",n,c,icls.icl());
00988                (void) new NrootXX("C",n,c,icls.icl());
00989              }
00990 
00991              (void) new SqrtXY("A",a,icls.icl());
00992              (void) new SqrtXY("B",b,icls.icl());
00993              (void) new SqrtXY("C",c,icls.icl());
00994 
00995              (void) new SqrtXX("A",a,icls.icl());
00996              (void) new SqrtXX("B",b,icls.icl());
00997              (void) new SqrtXX("C",c,icls.icl());
00998 
00999              (void) new AbsXY("A",a,icls.icl());
01000              (void) new AbsXY("B",b,icls.icl());
01001              (void) new AbsXY("C",c,icls.icl());
01002 
01003              (void) new AbsXX("A",a,icls.icl());
01004              (void) new AbsXX("B",b,icls.icl());
01005              (void) new AbsXX("C",c,icls.icl());
01006 
01007              (void) new MinXYZ("A",a,icls.icl());
01008              (void) new MinXYZ("B",b,icls.icl());
01009              (void) new MinXYZ("C",c,icls.icl());
01010 
01011              (void) new MinXXY("A",a,icls.icl());
01012              (void) new MinXXY("B",b,icls.icl());
01013              (void) new MinXXY("C",c,icls.icl());
01014 
01015              (void) new MinXYX("A",a,icls.icl());
01016              (void) new MinXYX("B",b,icls.icl());
01017              (void) new MinXYX("C",c,icls.icl());
01018 
01019              (void) new MinXYY("A",a,icls.icl());
01020              (void) new MinXYY("B",b,icls.icl());
01021              (void) new MinXYY("C",c,icls.icl());
01022 
01023              (void) new MinXXX("A",a,icls.icl());
01024              (void) new MinXXX("B",b,icls.icl());
01025              (void) new MinXXX("C",c,icls.icl());
01026 
01027              (void) new MaxXYZ("A",a,icls.icl());
01028              (void) new MaxXYZ("B",b,icls.icl());
01029              (void) new MaxXYZ("C",c,icls.icl());
01030 
01031              (void) new MaxXXY("A",a,icls.icl());
01032              (void) new MaxXXY("B",b,icls.icl());
01033              (void) new MaxXXY("C",c,icls.icl());
01034 
01035              (void) new MaxXYX("A",a,icls.icl());
01036              (void) new MaxXYX("B",b,icls.icl());
01037              (void) new MaxXYX("C",c,icls.icl());
01038 
01039              (void) new MaxXYY("A",a,icls.icl());
01040              (void) new MaxXYY("B",b,icls.icl());
01041              (void) new MaxXYY("C",c,icls.icl());
01042 
01043              (void) new MaxXXX("A",a,icls.icl());
01044              (void) new MaxXXX("B",b,icls.icl());
01045              (void) new MaxXXX("C",c,icls.icl());
01046 
01047              (void) new MinNary(icls.icl());
01048              (void) new MinNaryShared(icls.icl());
01049              (void) new MaxNary(icls.icl());
01050              (void) new MaxNaryShared(icls.icl());
01051            }
01052          for (int i=1; i<5; i++) {
01053            (void) new ArgMax(i,true);
01054            (void) new ArgMaxShared(i,true);
01055            (void) new ArgMin(i,true);
01056            (void) new ArgMinShared(i,true);
01057            (void) new ArgMax(i,false);
01058            (void) new ArgMaxShared(i,false);
01059            (void) new ArgMin(i,false);
01060            (void) new ArgMinShared(i,false);
01061          }
01062        }
01063      };
01064 
01065      Create c;
01067 
01068    }
01069 }}
01070 
01071 // STATISTICS: test-int