Generated on Thu Apr 11 13:58:55 2019 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  *  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 "test/int.hh"
00035 
00036 #include <cmath>
00037 #include <algorithm>
00038 
00039 #include <gecode/minimodel.hh>
00040 
00041 namespace Test { namespace Int {
00042 
00044    namespace Arithmetic {
00045 
00051 
00052      class MultXYZ : public Test {
00053      public:
00055        MultXYZ(const std::string& s, const Gecode::IntSet& d,
00056                Gecode::IntPropLevel ipl)
00057          : Test("Arithmetic::Mult::XYZ::"+str(ipl)+"::"+s,3,d,false,ipl) {}
00059        virtual bool solution(const Assignment& x) const {
00060          double d0 = static_cast<double>(x[0]);
00061          double d1 = static_cast<double>(x[1]);
00062          double d2 = static_cast<double>(x[2]);
00063          return d0*d1 == d2;
00064        }
00066        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00067          Gecode::mult(home, x[0], x[1], x[2], ipl);
00068        }
00069      };
00070 
00072      class MultXXY : public Test {
00073      public:
00075        MultXXY(const std::string& s, const Gecode::IntSet& d,
00076                Gecode::IntPropLevel ipl)
00077          : Test("Arithmetic::Mult::XXY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00079        virtual bool solution(const Assignment& x) const {
00080          double d0 = static_cast<double>(x[0]);
00081          double d1 = static_cast<double>(x[0]);
00082          double d2 = static_cast<double>(x[1]);
00083          return d0*d1 == d2;
00084        }
00086        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00087          Gecode::mult(home, x[0], x[0], x[1], ipl);
00088        }
00089      };
00090 
00092      class MultXYX : public Test {
00093      public:
00095        MultXYX(const std::string& s, const Gecode::IntSet& d,
00096                Gecode::IntPropLevel ipl)
00097          : Test("Arithmetic::Mult::XYX::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00099        virtual bool solution(const Assignment& x) const {
00100          double d0 = static_cast<double>(x[0]);
00101          double d1 = static_cast<double>(x[1]);
00102          double d2 = static_cast<double>(x[0]);
00103          return d0*d1 == d2;
00104        }
00106        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00107          Gecode::mult(home, x[0], x[1], x[0], ipl);
00108        }
00109      };
00110 
00112      class MultXYY : public Test {
00113      public:
00115        MultXYY(const std::string& s, const Gecode::IntSet& d,
00116                Gecode::IntPropLevel ipl)
00117          : Test("Arithmetic::Mult::XYY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00119        virtual bool solution(const Assignment& x) const {
00120          double d0 = static_cast<double>(x[0]);
00121          double d1 = static_cast<double>(x[1]);
00122          double d2 = static_cast<double>(x[1]);
00123          return d0*d1 == d2;
00124        }
00126        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00127          Gecode::mult(home, x[0], x[1], x[1], ipl);
00128        }
00129      };
00130 
00132      class MultXXX : public Test {
00133      public:
00135        MultXXX(const std::string& s, const Gecode::IntSet& d,
00136                Gecode::IntPropLevel ipl)
00137          : Test("Arithmetic::Mult::XXX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
00139        virtual bool solution(const Assignment& x) const {
00140          double d0 = static_cast<double>(x[0]);
00141          double d1 = static_cast<double>(x[0]);
00142          double d2 = static_cast<double>(x[0]);
00143          return d0*d1 == d2;
00144        }
00146        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00147          Gecode::mult(home, x[0], x[0], x[0], ipl);
00148        }
00149      };
00150 
00152      class SqrXY : public Test {
00153      public:
00155        SqrXY(const std::string& s, const Gecode::IntSet& d,
00156              Gecode::IntPropLevel ipl)
00157          : Test("Arithmetic::Sqr::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00159        virtual bool solution(const Assignment& x) const {
00160          double d0 = static_cast<double>(x[0]);
00161          double d1 = static_cast<double>(x[1]);
00162          return d0*d0 == d1;
00163        }
00165        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00166          Gecode::sqr(home, x[0], x[1], ipl);
00167        }
00168      };
00169 
00171      class SqrXX : public Test {
00172      public:
00174        SqrXX(const std::string& s, const Gecode::IntSet& d,
00175              Gecode::IntPropLevel ipl)
00176          : Test("Arithmetic::Sqr::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
00178        virtual bool solution(const Assignment& x) const {
00179          double d0 = static_cast<double>(x[0]);
00180          return d0*d0 == d0;
00181        }
00183        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00184          Gecode::sqr(home, x[0], x[0], ipl);
00185        }
00186      };
00187 
00189      class SqrtXY : public Test {
00190      public:
00192        SqrtXY(const std::string& s, const Gecode::IntSet& d,
00193               Gecode::IntPropLevel ipl)
00194          : Test("Arithmetic::Sqrt::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00196        virtual bool solution(const Assignment& x) const {
00197          double d0 = static_cast<double>(x[0]);
00198          double d1 = static_cast<double>(x[1]);
00199          return (d0 >= 0) && (d0 >= d1*d1) && (d0 < (d1+1)*(d1+1));
00200        }
00202        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00203          Gecode::sqrt(home, x[0], x[1], ipl);
00204        }
00205      };
00206 
00208      class SqrtXX : public Test {
00209      public:
00211        SqrtXX(const std::string& s, const Gecode::IntSet& d,
00212               Gecode::IntPropLevel ipl)
00213          : Test("Arithmetic::Sqrt::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
00215        virtual bool solution(const Assignment& x) const {
00216          double d0 = static_cast<double>(x[0]);
00217          return (d0 >= 0) && (d0 >= d0*d0) && (d0 < (d0+1)*(d0+1));
00218        }
00220        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00221          Gecode::sqrt(home, x[0], x[0], ipl);
00222        }
00223      };
00224 
00226      class PowXY : public Test {
00227      protected:
00229        int n;
00230      public:
00232        PowXY(const std::string& s, int n0, const Gecode::IntSet& d,
00233              Gecode::IntPropLevel ipl)
00234          : Test("Arithmetic::Pow::XY::"+str(n0)+"::"+str(ipl)+"::"+s,
00235                 2,d,false,ipl), n(n0) {}
00237        virtual bool solution(const Assignment& x) const {
00238          long long int p = 1;
00239          for (int i=0; i<n; i++) {
00240            p *= x[0];
00241            if ((p < Gecode::Int::Limits::min) ||
00242                (p > Gecode::Int::Limits::max))
00243              return false;
00244          }
00245          return p == x[1];
00246        }
00248        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00249          using namespace Gecode;
00250          if (n > 4)
00251            pow(home, x[0], n, x[1], ipl);
00252          else
00253            rel(home, expr(home, pow(x[0],n), ipl), IRT_EQ, x[1], ipl);
00254        }
00255      };
00256 
00258      class PowXX : public Test {
00259      protected:
00261        int n;
00262      public:
00264        PowXX(const std::string& s, int n0, const Gecode::IntSet& d,
00265              Gecode::IntPropLevel ipl)
00266          : Test("Arithmetic::Pow::XX::"+str(n0)+"::"+str(ipl)+"::"+s,
00267                 1,d,false,ipl), n(n0) {}
00269        virtual bool solution(const Assignment& x) const {
00270          long long int p = 1;
00271          for (int i=0; i<n; i++) {
00272            p *= x[0];
00273            if ((p < Gecode::Int::Limits::min) ||
00274                (p > Gecode::Int::Limits::max))
00275              return false;
00276          }
00277          return p == x[0];
00278        }
00280        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00281          Gecode::pow(home, x[0], n, x[0], ipl);
00282        }
00283      };
00284 
00285      bool powgr(int n, long long int r, int x) {
00286        assert(r >= 0);
00287        long long int y = r;
00288        long long int p = 1;
00289        do {
00290          p *= y; n--;
00291          if (p > x)
00292            return true;
00293        } while (n > 0);
00294        return false;
00295      }
00296 
00297      int fnroot(int n, int x) {
00298        if (x < 2)
00299          return x;
00300        /*
00301         * We look for l such that: l^n <= x < (l+1)^n
00302         */
00303        long long int l = 1;
00304        long long int u = x;
00305        do {
00306          long long int m = (l + u) >> 1;
00307          if (powgr(n,m,x)) u=m; else l=m;
00308        } while (l+1 < u);
00309        return static_cast<int>(l);
00310      }
00311 
00312      bool powle(int n, long long int r, int x) {
00313        assert(r >= 0);
00314        long long int y = r;
00315        long long int p = 1;
00316        do {
00317          p *= y; n--;
00318          if (p >= x)
00319            return false;
00320        } while (n > 0);
00321        assert(y < x);
00322        return true;
00323      }
00324 
00325      int cnroot(int n, int x) {
00326        if (x < 2)
00327          return x;
00328        /*
00329         * We look for u such that: (u-1)^n < x <= u^n
00330         */
00331        long long int l = 1;
00332        long long int u = x;
00333        do {
00334          long long int m = (l + u) >> 1;
00335          if (powle(n,m,x)) l=m; else u=m;
00336        } while (l+1 < u);
00337        return static_cast<int>(u);
00338      }
00339 
00341      class NrootXY : public Test {
00342      protected:
00344        int n;
00346      public:
00348        NrootXY(const std::string& s, int n0, const Gecode::IntSet& d,
00349              Gecode::IntPropLevel ipl)
00350          : Test("Arithmetic::Nroot::XY::"+str(n0)+"::"+str(ipl)+"::"+s,
00351                 2,d,false,ipl), n(n0) {}
00353        virtual bool solution(const Assignment& x) const {
00354          if (n == 1)
00355            return x[0] == x[1];
00356          if ((n % 2 == 0) && ((x[0] < 0) || (x[1] < 0)))
00357            return false;
00358          int r = (x[0] < 0) ? -cnroot(n,-x[0]) : fnroot(n,x[0]);
00359          return r == x[1];
00360        }
00362        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00363          using namespace Gecode;
00364          if (n > 4)
00365            nroot(home, x[0], n, x[1], ipl);
00366          else
00367            rel(home, expr(home, nroot(x[0],n), ipl), IRT_EQ, x[1], ipl);
00368        }
00369      };
00370 
00372      class NrootXX : public Test {
00373      protected:
00375        int n;
00376      public:
00378        NrootXX(const std::string& s, int n0, const Gecode::IntSet& d,
00379                Gecode::IntPropLevel ipl)
00380          : Test("Arithmetic::Nroot::XX::"+str(n0)+"::"+str(ipl)+"::"+s,
00381                 1,d,false,ipl), n(n0) {}
00383        virtual bool solution(const Assignment& x) const {
00384          if (n == 1)
00385            return true;
00386          if (n % 2 == 0) {
00387            return (x[0] >= 0) && (x[0] <= 1);
00388          } else {
00389            return (x[0] >= -2) && (x[0] <= 1);
00390          }
00391        }
00393        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00394          Gecode::nroot(home, x[0], n, x[0], ipl);
00395        }
00396      };
00397 
00399      class DivMod : public Test {
00400      private:
00402        static int abs(int a) { return a<0 ? -a:a; }
00404        static int sgn(int a) { return a<0 ? -1:1; }
00405      public:
00407        DivMod(const std::string& s, const Gecode::IntSet& d)
00408          : Test("Arithmetic::DivMod::"+s,4,d) {}
00410        virtual bool solution(const Assignment& x) const {
00411          return x[0] == x[1]*x[2]+x[3] &&
00412                 abs(x[3]) < abs(x[1]) &&
00413                 (x[3] == 0 || sgn(x[3]) == sgn(x[0]));
00414        }
00416        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00417          Gecode::divmod(home, x[0], x[1], x[2], x[3]);
00418        }
00419      };
00420 
00422      class Div : public Test {
00423      public:
00425        Div(const std::string& s, const Gecode::IntSet& d)
00426          : Test("Arithmetic::Div::"+s,3,d) {}
00428        virtual bool solution(const Assignment& x) const {
00429          if (x[1] == 0)
00430            return false;
00431          int divsign = (x[0] / x[1] < 0) ? -1 : 1;
00432          int divresult =
00433            divsign *
00434            static_cast<int>(floor(static_cast<double>(std::abs(x[0]))/
00435                                   static_cast<double>(std::abs(x[1]))));
00436          return x[2] == divresult;
00437        }
00439        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00440          Gecode::div(home, x[0], x[1], x[2]);
00441        }
00442      };
00443 
00445      class Mod : public Test {
00446      public:
00448        Mod(const std::string& s, const Gecode::IntSet& d)
00449          : Test("Arithmetic::Mod::"+s,3,d) {}
00451        virtual bool solution(const Assignment& x) const {
00452          if (x[1] == 0)
00453            return false;
00454          int divsign = (x[0] / x[1] < 0) ? -1 : 1;
00455          int divresult =
00456            divsign *
00457            static_cast<int>(floor(static_cast<double>(std::abs(x[0]))/
00458                                   static_cast<double>(std::abs(x[1]))));
00459          return x[0] == x[1]*divresult+x[2];
00460        }
00462        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00463          Gecode::mod(home, x[0], x[1], x[2]);
00464        }
00465      };
00466 
00468      class AbsXY : public Test {
00469      public:
00471        AbsXY(const std::string& s, const Gecode::IntSet& d,
00472              Gecode::IntPropLevel ipl)
00473          : Test("Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {}
00475        virtual bool solution(const Assignment& x) const {
00476          double d0 = static_cast<double>(x[0]);
00477          double d1 = static_cast<double>(x[1]);
00478          return (d0<0 ? -d0 : d0) == d1;
00479        }
00481        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00482          Gecode::abs(home, x[0], x[1], ipl);
00483        }
00484      };
00485 
00487      class AbsXX : public Test {
00488      public:
00490        AbsXX(const std::string& s, const Gecode::IntSet& d,
00491              Gecode::IntPropLevel ipl)
00492          : Test("Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {}
00494        virtual bool solution(const Assignment& x) const {
00495          double d0 = static_cast<double>(x[0]);
00496          double d1 = static_cast<double>(x[0]);
00497          return (d0<0 ? -d0 : d0) == d1;
00498        }
00500        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00501          Gecode::abs(home, x[0], x[0], ipl);
00502        }
00503      };
00504 
00506      class MinXYZ : public Test {
00507      public:
00509        MinXYZ(const std::string& s, const Gecode::IntSet& d,
00510               Gecode::IntPropLevel ipl)
00511          : Test("Arithmetic::Min::Bin::XYZ::"+str(ipl)+"::"+s,3,d,false,ipl) {}
00513        virtual bool solution(const Assignment& x) const {
00514          return std::min(x[0],x[1]) == x[2];
00515        }
00517        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00518          Gecode::min(home, x[0], x[1], x[2], ipl);
00519        }
00520      };
00521 
00523      class MinXXY : public Test {
00524      public:
00526        MinXXY(const std::string& s, const Gecode::IntSet& d,
00527               Gecode::IntPropLevel ipl)
00528          : Test("Arithmetic::Min::Bin::XYX::"+str(ipl)+"::"+s,2,d) {}
00530        virtual bool solution(const Assignment& x) const {
00531          return std::min(x[0],x[0]) == x[1];
00532        }
00534        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00535          Gecode::min(home, x[0], x[0], x[1], ipl);
00536        }
00537      };
00538 
00540      class MinXYX : public Test {
00541      public:
00543        MinXYX(const std::string& s, const Gecode::IntSet& d,
00544               Gecode::IntPropLevel ipl)
00545          : Test("Arithmetic::Min::Bin::XYX::"+str(ipl)+"::"+s,2,d) {}
00547        virtual bool solution(const Assignment& x) const {
00548          return std::min(x[0],x[1]) == x[0];
00549        }
00551        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00552          Gecode::min(home, x[0], x[1], x[0], ipl);
00553        }
00554      };
00555 
00557      class MinXYY : public Test {
00558      public:
00560        MinXYY(const std::string& s, const Gecode::IntSet& d,
00561               Gecode::IntPropLevel ipl)
00562          : Test("Arithmetic::Min::Bin::XYY::"+str(ipl)+"::"+s,2,d) {}
00564        virtual bool solution(const Assignment& x) const {
00565          return std::min(x[0],x[1]) == x[1];
00566        }
00568        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00569          Gecode::min(home, x[0], x[1], x[1], ipl);
00570        }
00571      };
00572 
00574      class MinXXX : public Test {
00575      public:
00577        MinXXX(const std::string& s, const Gecode::IntSet& d,
00578               Gecode::IntPropLevel ipl)
00579          : Test("Arithmetic::Min::Bin::XXX::"+str(ipl)+"::"+s,1,d) {}
00581        virtual bool solution(const Assignment& x) const {
00582          return std::min(x[0],x[0]) == x[0];
00583        }
00585        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00586          Gecode::min(home, x[0], x[0], x[0], ipl);
00587        }
00588      };
00589 
00591      class MaxXYZ : public Test {
00592      public:
00594        MaxXYZ(const std::string& s, const Gecode::IntSet& d,
00595               Gecode::IntPropLevel ipl)
00596          : Test("Arithmetic::Max::Bin::XYZ::"+str(ipl)+"::"+s,3,d) {
00597          contest = CTL_BOUNDS_Z;
00598        }
00600        virtual bool solution(const Assignment& x) const {
00601          return std::max(x[0],x[1]) == x[2];
00602        }
00604        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00605          Gecode::max(home, x[0], x[1], x[2], ipl);
00606        }
00607      };
00608 
00610      class MaxXXY : public Test {
00611      public:
00613        MaxXXY(const std::string& s, const Gecode::IntSet& d,
00614               Gecode::IntPropLevel ipl)
00615          : Test("Arithmetic::Max::Bin::XXY::"+str(ipl)+"::"+s,2,d) {}
00617        virtual bool solution(const Assignment& x) const {
00618          return std::max(x[0],x[0]) == x[1];
00619        }
00621        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00622          Gecode::max(home, x[0], x[0], x[1], ipl);
00623        }
00624      };
00625 
00627      class MaxXYX : public Test {
00628      public:
00630        MaxXYX(const std::string& s, const Gecode::IntSet& d,
00631               Gecode::IntPropLevel ipl)
00632          : Test("Arithmetic::Max::Bin::XYX::"+str(ipl)+"::"+s,2,d) {}
00634        virtual bool solution(const Assignment& x) const {
00635          return std::max(x[0],x[1]) == x[0];
00636        }
00638        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00639          Gecode::max(home, x[0], x[1], x[0], ipl);
00640        }
00641      };
00642 
00644      class MaxXYY : public Test {
00645      public:
00647        MaxXYY(const std::string& s, const Gecode::IntSet& d,
00648               Gecode::IntPropLevel ipl)
00649          : Test("Arithmetic::Max::Bin::XYY::"+str(ipl)+"::"+s,2,d) {}
00651        virtual bool solution(const Assignment& x) const {
00652          return std::max(x[0],x[1]) == x[1];
00653        }
00655        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00656          Gecode::max(home, x[0], x[1], x[1], ipl);
00657        }
00658      };
00659 
00661      class MaxXXX : public Test {
00662      public:
00664        MaxXXX(const std::string& s, const Gecode::IntSet& d,
00665               Gecode::IntPropLevel ipl)
00666          : Test("Arithmetic::Max::Bin::XXX::"+str(ipl)+"::"+s,1,d) {}
00668        virtual bool solution(const Assignment& x) const {
00669          return std::max(x[0],x[0]) == x[0];
00670        }
00672        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00673          Gecode::max(home, x[0], x[0], x[0], ipl);
00674        }
00675      };
00676 
00678      class MinNary : public Test {
00679      public:
00681        MinNary(Gecode::IntPropLevel ipl)
00682          : Test("Arithmetic::Min::Nary::"+str(ipl),4,-4,4,false,ipl) {}
00684        virtual bool solution(const Assignment& x) const {
00685          return std::min(std::min(x[0],x[1]), x[2]) == x[3];
00686        }
00688        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00689          Gecode::IntVarArgs m(3);
00690          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00691          Gecode::min(home, m, x[3], ipl);
00692        }
00693      };
00694 
00696      class MinNaryShared : public Test {
00697      public:
00699        MinNaryShared(Gecode::IntPropLevel ipl)
00700          : Test("Arithmetic::Min::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) {}
00702        virtual bool solution(const Assignment& x) const {
00703          return std::min(std::min(x[0],x[1]), x[2]) == x[1];
00704        }
00706        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00707          Gecode::IntVarArgs m(3);
00708          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00709          Gecode::min(home, m, x[1], ipl);
00710        }
00711      };
00712 
00714      class MaxNary : public Test {
00715      public:
00717        MaxNary(Gecode::IntPropLevel ipl)
00718          : Test("Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) {}
00720        virtual bool solution(const Assignment& x) const {
00721          return std::max(std::max(x[0],x[1]), x[2]) == x[3];
00722        }
00724        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00725          Gecode::IntVarArgs m(3);
00726          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00727          Gecode::max(home, m, x[3], ipl);
00728        }
00729      };
00730 
00732      class MaxNaryShared : public Test {
00733      public:
00735        MaxNaryShared(Gecode::IntPropLevel ipl)
00736          : Test("Arithmetic::Max::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) {}
00738        virtual bool solution(const Assignment& x) const {
00739          return std::max(std::max(x[0],x[1]), x[2]) == x[1];
00740        }
00742        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00743          Gecode::IntVarArgs m(3);
00744          m[0]=x[0]; m[1]=x[1]; m[2]=x[2];
00745          Gecode::max(home, m, x[1], ipl);
00746        }
00747      };
00748 
00750      class ArgMax : public Test {
00751      protected:
00753        int offset;
00755        bool tiebreak;
00756      public:
00758        ArgMax(int n, int o, bool tb)
00759          : Test("Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n),
00760                 n+1,0,n+1,
00761                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00762            offset(o), tiebreak(tb) {}
00764        virtual bool solution(const Assignment& x) const {
00765          int n=x.size()-1;
00766          if ((x[n] < offset) || (x[n] >= n + offset))
00767            return false;
00768          int m=x[0]; int p=0;
00769          for (int i=1; i<n; i++)
00770            if (x[i] > m) {
00771              p=i; m=x[i];
00772            }
00773          return tiebreak ? (p + offset == x[n]) : (m == x[x[n]-offset]);
00774        }
00776        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00777          int n=x.size()-1;
00778          Gecode::IntVarArgs m(n);
00779          for (int i=0; i<n; i++)
00780            m[i]=x[i];
00781          Gecode::argmax(home, m, offset, x[n], tiebreak);
00782        }
00783      };
00784 
00786      class ArgMaxShared : public Test {
00787      protected:
00789        bool tiebreak;
00790      public:
00792        ArgMaxShared(int n, bool tb)
00793          : Test("Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00794                 false),
00795            tiebreak(tb)  {
00796          testfix=false;
00797        }
00799        virtual bool solution(const Assignment& x) const {
00800          int n=x.size()-1;
00801          if ((x[n] < 0) || (x[n] >= 2*n))
00802            return false;
00803          Gecode::IntArgs y(2*n);
00804          for (int i=0; i<n; i++)
00805            y[2*i+0]=y[2*i+1]=x[i];
00806          int m=y[0]; int p=0;
00807          for (int i=1; i<2*n; i++)
00808            if (y[i] > m) {
00809              p=i; m=y[i];
00810            }
00811          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00812        }
00814        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00815          int n=x.size()-1;
00816          Gecode::IntVarArgs m(2*n);
00817          for (int i=0; i<n; i++)
00818            m[2*i+0]=m[2*i+1]=x[i];
00819          Gecode::argmax(home, m, x[n], tiebreak);
00820        }
00821      };
00822 
00824      class ArgMin : public Test {
00825      protected:
00827        int offset;
00829        bool tiebreak;
00830      public:
00832        ArgMin(int n, int o, bool tb)
00833          : Test("Arithmetic::ArgMin::"+str(o)+"::"+str(tb)+"::"+str(n),
00834                 n+1,0,n+1,
00835                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00836            offset(o), tiebreak(tb)  {}
00838        virtual bool solution(const Assignment& x) const {
00839          int n=x.size()-1;
00840          if ((x[n] < offset) || (x[n] >= n + offset))
00841            return false;
00842          int m=x[0]; int p=0;
00843          for (int i=1; i<n; i++)
00844            if (x[i] < m) {
00845              p=i; m=x[i];
00846            }
00847          return tiebreak ? (p+offset == x[n]) : (m == x[x[n]-offset]);
00848        }
00850        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00851          int n=x.size()-1;
00852          Gecode::IntVarArgs m(n);
00853          for (int i=0; i<n; i++)
00854            m[i]=x[i];
00855          Gecode::argmin(home, m, offset, x[n], tiebreak);
00856        }
00857      };
00858 
00860      class ArgMinShared : public Test {
00861      protected:
00863        bool tiebreak;
00864      public:
00866        ArgMinShared(int n, bool tb)
00867          : Test("Arithmetic::ArgMin::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00868                 false),
00869            tiebreak(tb) {
00870          testfix=false;
00871        }
00873        virtual bool solution(const Assignment& x) const {
00874          int n=x.size()-1;
00875          if ((x[n] < 0) || (x[n] >= 2*n))
00876            return false;
00877          Gecode::IntArgs y(2*n);
00878          for (int i=0; i<n; i++)
00879            y[2*i+0]=y[2*i+1]=x[i];
00880          int m=y[0]; int p=0;
00881          for (int i=1; i<2*n; i++)
00882            if (y[i] < m) {
00883              p=i; m=y[i];
00884            }
00885          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00886        }
00888        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00889          int n=x.size()-1;
00890          Gecode::IntVarArgs m(2*n);
00891          for (int i=0; i<n; i++)
00892            m[2*i+0]=m[2*i+1]=x[i];
00893          Gecode::argmin(home, m, x[n], tiebreak);
00894        }
00895      };
00896 
00898      class ArgMaxBool : public Test {
00899      protected:
00901        int offset;
00903        bool tiebreak;
00904      public:
00906        ArgMaxBool(int n, int o, bool tb)
00907          : Test("Arithmetic::ArgMaxBool::"+str(o)+"::"+str(tb)+"::"+str(n),
00908                 n+1,0,n+1,
00909                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00910            offset(o), tiebreak(tb) {}
00912        virtual bool solution(const Assignment& x) const {
00913          int n=x.size()-1;
00914          if ((x[n] < offset) || (x[n] >= n + offset))
00915            return false;
00916          int m=x[0]; int p=0;
00917          if (x[0] > 1)
00918            return false;
00919          for (int i=1; i<n; i++) {
00920            if (x[i] > 1)
00921              return false;
00922            if (x[i] > m) {
00923              p=i; m=x[i];
00924            }
00925          }
00926          return tiebreak ? (p + offset == x[n]) : (m == x[x[n]-offset]);
00927        }
00929        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00930          int n=x.size()-1;
00931          Gecode::BoolVarArgs m(n);
00932          for (int i=0; i<n; i++)
00933            m[i]=channel(home,x[i]);
00934          Gecode::argmax(home, m, offset, x[n], tiebreak);
00935        }
00936      };
00937 
00939      class ArgMaxBoolShared : public Test {
00940      protected:
00942        bool tiebreak;
00943      public:
00945        ArgMaxBoolShared(int n, bool tb)
00946          : Test("Arithmetic::ArgMaxBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
00947                 false),
00948            tiebreak(tb)  {
00949          testfix=false;
00950        }
00952        virtual bool solution(const Assignment& x) const {
00953          int n=x.size()-1;
00954          if ((x[n] < 0) || (x[n] >= 2*n))
00955            return false;
00956          Gecode::IntArgs y(2*n);
00957          for (int i=0; i<n; i++)
00958            y[2*i+0]=y[2*i+1]=x[i];
00959          int m=y[0]; int p=0;
00960          if (y[0] > 1)
00961            return false;
00962          for (int i=1; i<2*n; i++) {
00963            if (y[i] > 1)
00964              return false;
00965            if (y[i] > m) {
00966              p=i; m=y[i];
00967            }
00968          }
00969          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
00970        }
00972        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00973          int n=x.size()-1;
00974          Gecode::BoolVarArgs m(2*n);
00975          for (int i=0; i<n; i++)
00976            m[2*i+0]=m[2*i+1]=channel(home,x[i]);
00977          Gecode::argmax(home, m, x[n], tiebreak);
00978        }
00979      };
00980 
00982      class ArgMinBool : public Test {
00983      protected:
00985        int offset;
00987        bool tiebreak;
00988      public:
00990        ArgMinBool(int n, int o, bool tb)
00991          : Test("Arithmetic::ArgMinBool::"+str(o)+"::"+str(tb)+"::"+str(n),
00992                 n+1,0,n+1,
00993                 false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM),
00994            offset(o), tiebreak(tb)  {}
00996        virtual bool solution(const Assignment& x) const {
00997          int n=x.size()-1;
00998          if ((x[n] < offset) || (x[n] >= n + offset))
00999            return false;
01000          int m=x[0]; int p=0;
01001          if (x[0] < 0 || x[0] > 1)
01002            return false;
01003          for (int i=1; i<n; i++) {
01004            if (x[i] < 0 || x[i] > 1)
01005              return false;
01006            if (x[i] < m) {
01007              p=i; m=x[i];
01008            }
01009          }
01010          return tiebreak ? (p+offset == x[n]) : (m == x[x[n]-offset]);
01011        }
01013        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
01014          int n=x.size()-1;
01015          Gecode::BoolVarArgs m(n);
01016          for (int i=0; i<n; i++)
01017            m[i]=channel(home,x[i]);
01018          Gecode::argmin(home, m, offset, x[n], tiebreak);
01019        }
01020      };
01021 
01023      class ArgMinBoolShared : public Test {
01024      protected:
01026        bool tiebreak;
01027      public:
01029        ArgMinBoolShared(int n, bool tb)
01030          : Test("Arithmetic::ArgMinBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1,
01031                 false),
01032            tiebreak(tb) {
01033          testfix=false;
01034        }
01036        virtual bool solution(const Assignment& x) const {
01037          int n=x.size()-1;
01038          if ((x[n] < 0) || (x[n] >= 2*n))
01039            return false;
01040          Gecode::IntArgs y(2*n);
01041          for (int i=0; i<n; i++)
01042            y[2*i+0]=y[2*i+1]=x[i];
01043          int m=y[0]; int p=0;
01044          if (y[0] > 1)
01045            return false;
01046          for (int i=1; i<2*n; i++) {
01047            if (y[i] > 1)
01048              return false;
01049            if (y[i] < m) {
01050              p=i; m=y[i];
01051            }
01052          }
01053          return tiebreak ? (p == x[n]) : (m == y[x[n]]);
01054        }
01056        virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
01057          int n=x.size()-1;
01058          Gecode::BoolVarArgs m(2*n);
01059          for (int i=0; i<n; i++)
01060            m[2*i+0]=m[2*i+1]=channel(home,x[i]);
01061          Gecode::argmin(home, m, x[n], tiebreak);
01062        }
01063      };
01064 
01066      class Create {
01067      public:
01069        Create(void) {
01070 
01071          const int va[7] = {
01072            Gecode::Int::Limits::min, Gecode::Int::Limits::min+1,
01073            -1,0,1,
01074            Gecode::Int::Limits::max-1, Gecode::Int::Limits::max
01075          };
01076          const int vb[9] = {
01077            static_cast<int>(-sqrt(static_cast<double>
01078                                   (-Gecode::Int::Limits::min))),
01079            -4,-2,-1,0,1,2,4,
01080            static_cast<int>(sqrt(static_cast<double>
01081                                  (Gecode::Int::Limits::max)))
01082          };
01083 
01084          Gecode::IntSet a(va,7);
01085          Gecode::IntSet b(vb,9);
01086          Gecode::IntSet c(-8,8);
01087          Gecode::IntSet d(-70,70);
01088 
01089          (void) new DivMod("A",a);
01090          (void) new DivMod("B",b);
01091          (void) new DivMod("C",c);
01092 
01093          (void) new Div("A",a);
01094          (void) new Div("B",b);
01095          (void) new Div("C",c);
01096 
01097          (void) new Mod("A",a);
01098          (void) new Mod("B",b);
01099          (void) new Mod("C",c);
01100 
01101 
01102          for (IntPropLevels ipls; ipls(); ++ipls) {
01103            (void) new AbsXY("A",a,ipls.ipl());
01104            (void) new AbsXY("B",b,ipls.ipl());
01105            (void) new AbsXY("C",c,ipls.ipl());
01106 
01107            (void) new AbsXX("A",a,ipls.ipl());
01108            (void) new AbsXX("B",b,ipls.ipl());
01109            (void) new AbsXX("C",c,ipls.ipl());
01110            if (ipls.ipl() != Gecode::IPL_VAL) {
01111              (void) new MultXYZ("A",a,ipls.ipl());
01112              (void) new MultXYZ("B",b,ipls.ipl());
01113              (void) new MultXYZ("C",c,ipls.ipl());
01114 
01115              (void) new MultXXY("A",a,ipls.ipl());
01116              (void) new MultXXY("B",b,ipls.ipl());
01117              (void) new MultXXY("C",c,ipls.ipl());
01118 
01119              (void) new MultXYX("A",a,ipls.ipl());
01120              (void) new MultXYX("B",b,ipls.ipl());
01121              (void) new MultXYX("C",c,ipls.ipl());
01122 
01123              (void) new MultXYY("A",a,ipls.ipl());
01124              (void) new MultXYY("B",b,ipls.ipl());
01125              (void) new MultXYY("C",c,ipls.ipl());
01126 
01127              (void) new MultXXX("A",a,ipls.ipl());
01128              (void) new MultXXX("B",b,ipls.ipl());
01129              (void) new MultXXX("C",c,ipls.ipl());
01130 
01131              (void) new SqrXY("A",a,ipls.ipl());
01132              (void) new SqrXY("B",b,ipls.ipl());
01133              (void) new SqrXY("C",c,ipls.ipl());
01134 
01135              (void) new SqrXX("A",a,ipls.ipl());
01136              (void) new SqrXX("B",b,ipls.ipl());
01137              (void) new SqrXX("C",c,ipls.ipl());
01138 
01139              for (int n=0; n<=6; n++) {
01140                (void) new PowXY("A",n,a,ipls.ipl());
01141                (void) new PowXY("B",n,b,ipls.ipl());
01142                (void) new PowXY("C",n,c,ipls.ipl());
01143                (void) new PowXY("D",n,d,ipls.ipl());
01144 
01145                (void) new PowXX("A",n,a,ipls.ipl());
01146                (void) new PowXX("B",n,b,ipls.ipl());
01147                (void) new PowXX("C",n,c,ipls.ipl());
01148                (void) new PowXX("D",n,d,ipls.ipl());
01149              }
01150 
01151              for (int n=1; n<=6; n++) {
01152                (void) new NrootXY("A",n,a,ipls.ipl());
01153                (void) new NrootXY("B",n,b,ipls.ipl());
01154                (void) new NrootXY("C",n,c,ipls.ipl());
01155                (void) new NrootXY("D",n,d,ipls.ipl());
01156 
01157                (void) new NrootXX("A",n,a,ipls.ipl());
01158                (void) new NrootXX("B",n,b,ipls.ipl());
01159                (void) new NrootXX("C",n,c,ipls.ipl());
01160                (void) new NrootXX("D",n,d,ipls.ipl());
01161              }
01162 
01163              for (int n=30; n<=34; n++) {
01164                (void) new PowXY("C",n,c,ipls.ipl());
01165                (void) new PowXX("C",n,c,ipls.ipl());
01166                (void) new NrootXY("C",n,c,ipls.ipl());
01167                (void) new NrootXX("C",n,c,ipls.ipl());
01168              }
01169 
01170              (void) new SqrtXY("A",a,ipls.ipl());
01171              (void) new SqrtXY("B",b,ipls.ipl());
01172              (void) new SqrtXY("C",c,ipls.ipl());
01173 
01174              (void) new SqrtXX("A",a,ipls.ipl());
01175              (void) new SqrtXX("B",b,ipls.ipl());
01176              (void) new SqrtXX("C",c,ipls.ipl());
01177 
01178              (void) new MinXYZ("A",a,ipls.ipl());
01179              (void) new MinXYZ("B",b,ipls.ipl());
01180              (void) new MinXYZ("C",c,ipls.ipl());
01181 
01182              (void) new MinXXY("A",a,ipls.ipl());
01183              (void) new MinXXY("B",b,ipls.ipl());
01184              (void) new MinXXY("C",c,ipls.ipl());
01185 
01186              (void) new MinXYX("A",a,ipls.ipl());
01187              (void) new MinXYX("B",b,ipls.ipl());
01188              (void) new MinXYX("C",c,ipls.ipl());
01189 
01190              (void) new MinXYY("A",a,ipls.ipl());
01191              (void) new MinXYY("B",b,ipls.ipl());
01192              (void) new MinXYY("C",c,ipls.ipl());
01193 
01194              (void) new MinXXX("A",a,ipls.ipl());
01195              (void) new MinXXX("B",b,ipls.ipl());
01196              (void) new MinXXX("C",c,ipls.ipl());
01197 
01198              (void) new MaxXYZ("A",a,ipls.ipl());
01199              (void) new MaxXYZ("B",b,ipls.ipl());
01200              (void) new MaxXYZ("C",c,ipls.ipl());
01201 
01202              (void) new MaxXXY("A",a,ipls.ipl());
01203              (void) new MaxXXY("B",b,ipls.ipl());
01204              (void) new MaxXXY("C",c,ipls.ipl());
01205 
01206              (void) new MaxXYX("A",a,ipls.ipl());
01207              (void) new MaxXYX("B",b,ipls.ipl());
01208              (void) new MaxXYX("C",c,ipls.ipl());
01209 
01210              (void) new MaxXYY("A",a,ipls.ipl());
01211              (void) new MaxXYY("B",b,ipls.ipl());
01212              (void) new MaxXYY("C",c,ipls.ipl());
01213 
01214              (void) new MaxXXX("A",a,ipls.ipl());
01215              (void) new MaxXXX("B",b,ipls.ipl());
01216              (void) new MaxXXX("C",c,ipls.ipl());
01217 
01218              (void) new MinNary(ipls.ipl());
01219              (void) new MinNaryShared(ipls.ipl());
01220              (void) new MaxNary(ipls.ipl());
01221              (void) new MaxNaryShared(ipls.ipl());
01222            }
01223          }
01224 
01225          for (int i=1; i<5; i++) {
01226            (void) new ArgMax(i,0,true);
01227            (void) new ArgMax(i,1,true);
01228            (void) new ArgMaxShared(i,true);
01229            (void) new ArgMin(i,0,true);
01230            (void) new ArgMin(i,1,true);
01231            (void) new ArgMinShared(i,true);
01232            (void) new ArgMax(i,0,false);
01233            (void) new ArgMax(i,1,false);
01234            (void) new ArgMaxShared(i,false);
01235            (void) new ArgMin(i,0,false);
01236            (void) new ArgMin(i,1,false);
01237            (void) new ArgMinShared(i,false);
01238 
01239            (void) new ArgMaxBool(i,0,true);
01240            (void) new ArgMaxBool(i,1,true);
01241            (void) new ArgMaxBoolShared(i,true);
01242            (void) new ArgMinBool(i,0,true);
01243            (void) new ArgMinBool(i,1,true);
01244            (void) new ArgMinBoolShared(i,true);
01245            (void) new ArgMaxBool(i,0,false);
01246            (void) new ArgMaxBool(i,1,false);
01247            (void) new ArgMaxBoolShared(i,false);
01248            (void) new ArgMinBool(i,0,false);
01249            (void) new ArgMinBool(i,1,false);
01250            (void) new ArgMinBoolShared(i,false);
01251          }
01252        }
01253      };
01254 
01255      Create c;
01257 
01258    }
01259 }}
01260 
01261 // STATISTICS: test-int