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, 2005
00008  *
00009  *  Last modified:
00010  *     $Date: 2017-02-22 03:37:18 +0100 (Wed, 22 Feb 2017) $ by $Author: schulte $
00011  *     $Revision: 15468 $
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::IntPropLevel ipl)
00061          : Test("Arithmetic::Mult::XYZ::"+str(ipl)+"::"+s,3,d,false,ipl) {}
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], ipl);
00072        }
00073      };
00074 
00076      class MultXXY : public Test {
00077      public:
00079        MultXXY(const std::string& s, const Gecode::IntSet& d,
00080                Gecode::IntPropLevel ipl)
00081          : Test("Arithmetic::Mult::XXY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00092        }
00093      };
00094 
00096      class MultXYX : public Test {
00097      public:
00099        MultXYX(const std::string& s, const Gecode::IntSet& d,
00100                Gecode::IntPropLevel ipl)
00101          : Test("Arithmetic::Mult::XYX::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00112        }
00113      };
00114 
00116      class MultXYY : public Test {
00117      public:
00119        MultXYY(const std::string& s, const Gecode::IntSet& d,
00120                Gecode::IntPropLevel ipl)
00121          : Test("Arithmetic::Mult::XYY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00132        }
00133      };
00134 
00136      class MultXXX : public Test {
00137      public:
00139        MultXXX(const std::string& s, const Gecode::IntSet& d,
00140                Gecode::IntPropLevel ipl)
00141          : Test("Arithmetic::Mult::XXX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
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], ipl);
00152        }
00153      };
00154 
00156      class SqrXY : public Test {
00157      public:
00159        SqrXY(const std::string& s, const Gecode::IntSet& d,
00160              Gecode::IntPropLevel ipl)
00161          : Test("Arithmetic::Sqr::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00171        }
00172      };
00173 
00175      class SqrXX : public Test {
00176      public:
00178        SqrXX(const std::string& s, const Gecode::IntSet& d,
00179              Gecode::IntPropLevel ipl)
00180          : Test("Arithmetic::Sqr::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
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], ipl);
00189        }
00190      };
00191 
00193      class SqrtXY : public Test {
00194      public:
00196        SqrtXY(const std::string& s, const Gecode::IntSet& d,
00197               Gecode::IntPropLevel ipl)
00198          : Test("Arithmetic::Sqrt::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00208        }
00209      };
00210 
00212      class SqrtXX : public Test {
00213      public:
00215        SqrtXX(const std::string& s, const Gecode::IntSet& d,
00216               Gecode::IntPropLevel ipl)
00217          : Test("Arithmetic::Sqrt::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
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], ipl);
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::IntPropLevel ipl)
00238          : Test("Arithmetic::Pow::XY::"+str(n0)+"::"+str(ipl)+"::"+s,
00239                 2,d,false,ipl), 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], ipl);
00256          else
00257            rel(home, expr(home, pow(x[0],n), ipl), IRT_EQ, x[1], ipl);
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::IntPropLevel ipl)
00270          : Test("Arithmetic::Pow::XX::"+str(n0)+"::"+str(ipl)+"::"+s,
00271                 1,d,false,ipl), 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], ipl);
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::IntPropLevel ipl)
00354          : Test("Arithmetic::Nroot::XY::"+str(n0)+"::"+str(ipl)+"::"+s,
00355                 2,d,false,ipl), 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], ipl);
00370          else
00371            rel(home, expr(home, nroot(x[0],n), ipl), IRT_EQ, x[1], ipl);
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::IntPropLevel ipl)
00384          : Test("Arithmetic::Nroot::XX::"+str(n0)+"::"+str(ipl)+"::"+s,
00385                 1,d,false,ipl), 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], ipl);
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::IntPropLevel ipl)
00477          : Test("Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
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], ipl);
00487        }
00488      };
00489 
00491      class AbsXX : public Test {
00492      public:
00494        AbsXX(const std::string& s, const Gecode::IntSet& d,
00495              Gecode::IntPropLevel ipl)
00496          : Test("Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
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], ipl);
00506        }
00507      };
00508 
00510      class MinXYZ : public Test {
00511      public:
00513        MinXYZ(const std::string& s, const Gecode::IntSet& d,
00514               Gecode::IntPropLevel ipl)
00515          : Test("Arithmetic::Min::Bin::XYZ::"+str(ipl)+"::"+s,3,d,false,ipl) {}
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], ipl);
00523        }
00524      };
00525 
00527      class MinXXY : public Test {
00528      public:
00530        MinXXY(const std::string& s, const Gecode::IntSet& d,
00531               Gecode::IntPropLevel ipl)
00532          : Test("Arithmetic::Min::Bin::XYX::"+str(ipl)+"::"+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], ipl);
00540        }
00541      };
00542 
00544      class MinXYX : public Test {
00545      public:
00547        MinXYX(const std::string& s, const Gecode::IntSet& d,
00548               Gecode::IntPropLevel ipl)
00549          : Test("Arithmetic::Min::Bin::XYX::"+str(ipl)+"::"+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], ipl);
00557        }
00558      };
00559 
00561      class MinXYY : public Test {
00562      public:
00564        MinXYY(const std::string& s, const Gecode::IntSet& d,
00565               Gecode::IntPropLevel ipl)
00566          : Test("Arithmetic::Min::Bin::XYY::"+str(ipl)+"::"+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], ipl);
00574        }
00575      };
00576 
00578      class MinXXX : public Test {
00579      public:
00581        MinXXX(const std::string& s, const Gecode::IntSet& d,
00582               Gecode::IntPropLevel ipl)
00583          : Test("Arithmetic::Min::Bin::XXX::"+str(ipl)+"::"+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], ipl);
00591        }
00592      };
00593 
00595      class MaxXYZ : public Test {
00596      public:
00598        MaxXYZ(const std::string& s, const Gecode::IntSet& d,
00599               Gecode::IntPropLevel ipl)
00600          : Test("Arithmetic::Max::Bin::XYZ::"+str(ipl)+"::"+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], ipl);
00610        }
00611      };
00612 
00614      class MaxXXY : public Test {
00615      public:
00617        MaxXXY(const std::string& s, const Gecode::IntSet& d,
00618               Gecode::IntPropLevel ipl)
00619          : Test("Arithmetic::Max::Bin::XXY::"+str(ipl)+"::"+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], ipl);
00627        }
00628      };
00629 
00631      class MaxXYX : public Test {
00632      public:
00634        MaxXYX(const std::string& s, const Gecode::IntSet& d,
00635               Gecode::IntPropLevel ipl)
00636          : Test("Arithmetic::Max::Bin::XYX::"+str(ipl)+"::"+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], ipl);
00644        }
00645      };
00646 
00648      class MaxXYY : public Test {
00649      public:
00651        MaxXYY(const std::string& s, const Gecode::IntSet& d,
00652               Gecode::IntPropLevel ipl)
00653          : Test("Arithmetic::Max::Bin::XYY::"+str(ipl)+"::"+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], ipl);
00661        }
00662      };
00663 
00665      class MaxXXX : public Test {
00666      public:
00668        MaxXXX(const std::string& s, const Gecode::IntSet& d,
00669               Gecode::IntPropLevel ipl)
00670          : Test("Arithmetic::Max::Bin::XXX::"+str(ipl)+"::"+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], ipl);
00678        }
00679      };
00680 
00682      class MinNary : public Test {
00683      public:
00685        MinNary(Gecode::IntPropLevel ipl)
00686          : Test("Arithmetic::Min::Nary::"+str(ipl),4,-4,4,false,ipl) {}
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], ipl);
00696        }
00697      };
00698 
00700      class MinNaryShared : public Test {
00701      public:
00703        MinNaryShared(Gecode::IntPropLevel ipl)
00704          : Test("Arithmetic::Min::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) {}
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], ipl);
00714        }
00715      };
00716 
00718      class MaxNary : public Test {
00719      public:
00721        MaxNary(Gecode::IntPropLevel ipl)
00722          : Test("Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) {}
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], ipl);
00732        }
00733      };
00734 
00736      class MaxNaryShared : public Test {
00737      public:
00739        MaxNaryShared(Gecode::IntPropLevel ipl)
00740          : Test("Arithmetic::Max::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) {}
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], ipl);
00750        }
00751      };
00752 
00754      class ArgMax : public Test {
00755      protected:
00757        int offset;
00759        bool tiebreak;
00760      public:
00762        ArgMax(int n, int o, bool tb)
00763          : Test("Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n),
00764                 n+1,0,n+1,
00765                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00766            offset(o), tiebreak(tb) {}
00768        virtual bool solution(const Assignment& x) const {
00769          int n=x.size()-1;
00770          if ((x[n] < offset) || (x[n] >= n + offset))
00771            return false;
00772          int m=x[0]; int p=0;
00773          for (int i=1; i<n; i++)
00774            if (x[i] > m) {
00775              p=i; m=x[i];
00776            }
00777          return tiebreak ? (p + offset == x[n]) : (m == x[x[n]-offset]);
00778        }
00780        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00781          int n=x.size()-1;
00782          Gecode::IntVarArgs m(n);
00783          for (int i=0; i<n; i++)
00784            m[i]=x[i];
00785          Gecode::argmax(home, m, offset, x[n], tiebreak);
00786        }
00787      };
00788 
00790      class ArgMaxShared : public Test {
00791      protected:
00793        bool tiebreak;
00794      public:
00796        ArgMaxShared(int n, bool tb)
00797          : Test("Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00798                 false),
00799            tiebreak(tb)  {
00800          testfix=false;
00801        }
00803        virtual bool solution(const Assignment& x) const {
00804          int n=x.size()-1;
00805          if ((x[n] < 0) || (x[n] >= 2*n))
00806            return false;
00807          Gecode::IntArgs y(2*n);
00808          for (int i=0; i<n; i++)
00809            y[2*i+0]=y[2*i+1]=x[i];
00810          int m=y[0]; int p=0;
00811          for (int i=1; i<2*n; i++)
00812            if (y[i] > m) {
00813              p=i; m=y[i];
00814            }
00815          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00816        }
00818        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00819          int n=x.size()-1;
00820          Gecode::IntVarArgs m(2*n);
00821          for (int i=0; i<n; i++)
00822            m[2*i+0]=m[2*i+1]=x[i];
00823          Gecode::argmax(home, m, x[n], tiebreak);
00824        }
00825      };
00826 
00828      class ArgMin : public Test {
00829      protected:
00831        int offset;
00833        bool tiebreak;
00834      public:
00836        ArgMin(int n, int o, bool tb)
00837          : Test("Arithmetic::ArgMin::"+str(o)+"::"+str(tb)+"::"+str(n),
00838                 n+1,0,n+1,
00839                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00840            offset(o), tiebreak(tb)  {}
00842        virtual bool solution(const Assignment& x) const {
00843          int n=x.size()-1;
00844          if ((x[n] < offset) || (x[n] >= n + offset))
00845            return false;
00846          int m=x[0]; int p=0;
00847          for (int i=1; i<n; i++)
00848            if (x[i] < m) {
00849              p=i; m=x[i];
00850            }
00851          return tiebreak ? (p+offset == x[n]) : (m == x[x[n]-offset]);
00852        }
00854        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00855          int n=x.size()-1;
00856          Gecode::IntVarArgs m(n);
00857          for (int i=0; i<n; i++)
00858            m[i]=x[i];
00859          Gecode::argmin(home, m, offset, x[n], tiebreak);
00860        }
00861      };
00862 
00864      class ArgMinShared : public Test {
00865      protected:
00867        bool tiebreak;
00868      public:
00870        ArgMinShared(int n, bool tb)
00871          : Test("Arithmetic::ArgMin::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00872                 false),
00873            tiebreak(tb) {
00874          testfix=false;
00875        }
00877        virtual bool solution(const Assignment& x) const {
00878          int n=x.size()-1;
00879          if ((x[n] < 0) || (x[n] >= 2*n))
00880            return false;
00881          Gecode::IntArgs y(2*n);
00882          for (int i=0; i<n; i++)
00883            y[2*i+0]=y[2*i+1]=x[i];
00884          int m=y[0]; int p=0;
00885          for (int i=1; i<2*n; i++)
00886            if (y[i] < m) {
00887              p=i; m=y[i];
00888            }
00889          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00890        }
00892        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00893          int n=x.size()-1;
00894          Gecode::IntVarArgs m(2*n);
00895          for (int i=0; i<n; i++)
00896            m[2*i+0]=m[2*i+1]=x[i];
00897          Gecode::argmin(home, m, x[n], tiebreak);
00898        }
00899      };
00900 
00901 
00902 
00904      class Create {
00905      public:
00907        Create(void) {
00908 
00909          const int va[7] = {
00910            Gecode::Int::Limits::min, Gecode::Int::Limits::min+1,
00911            -1,0,1,
00912            Gecode::Int::Limits::max-1, Gecode::Int::Limits::max
00913          };
00914          const int vb[9] = {
00915            static_cast<int>(-sqrt(static_cast<double>
00916                                   (-Gecode::Int::Limits::min))),
00917            -4,-2,-1,0,1,2,4,
00918            static_cast<int>(sqrt(static_cast<double>
00919                                  (Gecode::Int::Limits::max)))
00920          };
00921 
00922          Gecode::IntSet a(va,7);
00923          Gecode::IntSet b(vb,9);
00924          Gecode::IntSet c(-8,8);
00925          Gecode::IntSet d(-70,70);
00926 
00927          (void) new DivMod("A",a);
00928          (void) new DivMod("B",b);
00929          (void) new DivMod("C",c);
00930 
00931          (void) new Div("A",a);
00932          (void) new Div("B",b);
00933          (void) new Div("C",c);
00934 
00935          (void) new Mod("A",a);
00936          (void) new Mod("B",b);
00937          (void) new Mod("C",c);
00938 
00939 
00940          for (IntPropLevels ipls; ipls(); ++ipls) {
00941            (void) new AbsXY("A",a,ipls.ipl());
00942            (void) new AbsXY("B",b,ipls.ipl());
00943            (void) new AbsXY("C",c,ipls.ipl());
00944 
00945            (void) new AbsXX("A",a,ipls.ipl());
00946            (void) new AbsXX("B",b,ipls.ipl());
00947            (void) new AbsXX("C",c,ipls.ipl());
00948            if (ipls.ipl() != Gecode::IPL_VAL) {
00949              (void) new MultXYZ("A",a,ipls.ipl());
00950              (void) new MultXYZ("B",b,ipls.ipl());
00951              (void) new MultXYZ("C",c,ipls.ipl());
00952 
00953              (void) new MultXXY("A",a,ipls.ipl());
00954              (void) new MultXXY("B",b,ipls.ipl());
00955              (void) new MultXXY("C",c,ipls.ipl());
00956 
00957              (void) new MultXYX("A",a,ipls.ipl());
00958              (void) new MultXYX("B",b,ipls.ipl());
00959              (void) new MultXYX("C",c,ipls.ipl());
00960 
00961              (void) new MultXYY("A",a,ipls.ipl());
00962              (void) new MultXYY("B",b,ipls.ipl());
00963              (void) new MultXYY("C",c,ipls.ipl());
00964 
00965              (void) new MultXXX("A",a,ipls.ipl());
00966              (void) new MultXXX("B",b,ipls.ipl());
00967              (void) new MultXXX("C",c,ipls.ipl());
00968 
00969              (void) new SqrXY("A",a,ipls.ipl());
00970              (void) new SqrXY("B",b,ipls.ipl());
00971              (void) new SqrXY("C",c,ipls.ipl());
00972 
00973              (void) new SqrXX("A",a,ipls.ipl());
00974              (void) new SqrXX("B",b,ipls.ipl());
00975              (void) new SqrXX("C",c,ipls.ipl());
00976 
00977              for (int n=0; n<=6; n++) {
00978                (void) new PowXY("A",n,a,ipls.ipl());
00979                (void) new PowXY("B",n,b,ipls.ipl());
00980                (void) new PowXY("C",n,c,ipls.ipl());
00981                (void) new PowXY("D",n,d,ipls.ipl());
00982 
00983                (void) new PowXX("A",n,a,ipls.ipl());
00984                (void) new PowXX("B",n,b,ipls.ipl());
00985                (void) new PowXX("C",n,c,ipls.ipl());
00986                (void) new PowXX("D",n,d,ipls.ipl());
00987              }
00988 
00989              for (int n=1; n<=6; n++) {
00990                (void) new NrootXY("A",n,a,ipls.ipl());
00991                (void) new NrootXY("B",n,b,ipls.ipl());
00992                (void) new NrootXY("C",n,c,ipls.ipl());
00993                (void) new NrootXY("D",n,d,ipls.ipl());
00994 
00995                (void) new NrootXX("A",n,a,ipls.ipl());
00996                (void) new NrootXX("B",n,b,ipls.ipl());
00997                (void) new NrootXX("C",n,c,ipls.ipl());
00998                (void) new NrootXX("D",n,d,ipls.ipl());
00999              }
01000 
01001              for (int n=30; n<=34; n++) {
01002                (void) new PowXY("C",n,c,ipls.ipl());
01003                (void) new PowXX("C",n,c,ipls.ipl());
01004                (void) new NrootXY("C",n,c,ipls.ipl());
01005                (void) new NrootXX("C",n,c,ipls.ipl());
01006              }
01007 
01008              (void) new SqrtXY("A",a,ipls.ipl());
01009              (void) new SqrtXY("B",b,ipls.ipl());
01010              (void) new SqrtXY("C",c,ipls.ipl());
01011 
01012              (void) new SqrtXX("A",a,ipls.ipl());
01013              (void) new SqrtXX("B",b,ipls.ipl());
01014              (void) new SqrtXX("C",c,ipls.ipl());
01015 
01016              (void) new MinXYZ("A",a,ipls.ipl());
01017              (void) new MinXYZ("B",b,ipls.ipl());
01018              (void) new MinXYZ("C",c,ipls.ipl());
01019 
01020              (void) new MinXXY("A",a,ipls.ipl());
01021              (void) new MinXXY("B",b,ipls.ipl());
01022              (void) new MinXXY("C",c,ipls.ipl());
01023 
01024              (void) new MinXYX("A",a,ipls.ipl());
01025              (void) new MinXYX("B",b,ipls.ipl());
01026              (void) new MinXYX("C",c,ipls.ipl());
01027 
01028              (void) new MinXYY("A",a,ipls.ipl());
01029              (void) new MinXYY("B",b,ipls.ipl());
01030              (void) new MinXYY("C",c,ipls.ipl());
01031 
01032              (void) new MinXXX("A",a,ipls.ipl());
01033              (void) new MinXXX("B",b,ipls.ipl());
01034              (void) new MinXXX("C",c,ipls.ipl());
01035 
01036              (void) new MaxXYZ("A",a,ipls.ipl());
01037              (void) new MaxXYZ("B",b,ipls.ipl());
01038              (void) new MaxXYZ("C",c,ipls.ipl());
01039 
01040              (void) new MaxXXY("A",a,ipls.ipl());
01041              (void) new MaxXXY("B",b,ipls.ipl());
01042              (void) new MaxXXY("C",c,ipls.ipl());
01043 
01044              (void) new MaxXYX("A",a,ipls.ipl());
01045              (void) new MaxXYX("B",b,ipls.ipl());
01046              (void) new MaxXYX("C",c,ipls.ipl());
01047 
01048              (void) new MaxXYY("A",a,ipls.ipl());
01049              (void) new MaxXYY("B",b,ipls.ipl());
01050              (void) new MaxXYY("C",c,ipls.ipl());
01051 
01052              (void) new MaxXXX("A",a,ipls.ipl());
01053              (void) new MaxXXX("B",b,ipls.ipl());
01054              (void) new MaxXXX("C",c,ipls.ipl());
01055 
01056              (void) new MinNary(ipls.ipl());
01057              (void) new MinNaryShared(ipls.ipl());
01058              (void) new MaxNary(ipls.ipl());
01059              (void) new MaxNaryShared(ipls.ipl());
01060            }
01061          }
01062 
01063          for (int i=1; i<5; i++) {
01064            (void) new ArgMax(i,0,true);
01065            (void) new ArgMax(i,1,true);
01066            (void) new ArgMaxShared(i,true);
01067            (void) new ArgMin(i,0,true);
01068            (void) new ArgMin(i,1,true);
01069            (void) new ArgMinShared(i,true);
01070            (void) new ArgMax(i,0,false);
01071            (void) new ArgMax(i,1,false);
01072            (void) new ArgMaxShared(i,false);
01073            (void) new ArgMin(i,0,false);
01074            (void) new ArgMin(i,1,false);
01075            (void) new ArgMinShared(i,false);
01076          }
01077        }
01078      };
01079 
01080      Create c;
01082 
01083    }
01084 }}
01085 
01086 // STATISTICS: test-int