00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <gecode/int/arithmetic.hh>
00039
00040 namespace Gecode {
00041
00042 void
00043 abs(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00044 using namespace Int;
00045 if (home.failed()) return;
00046 if (icl == ICL_DOM) {
00047 GECODE_ES_FAIL(Arithmetic::AbsDom<IntView>::post(home,x0,x1));
00048 } else {
00049 GECODE_ES_FAIL(Arithmetic::AbsBnd<IntView>::post(home,x0,x1));
00050 }
00051 }
00052
00053
00054 void
00055 max(Home home, IntVar x0, IntVar x1, IntVar x2,
00056 IntConLevel icl) {
00057 using namespace Int;
00058 if (home.failed()) return;
00059 if (icl == ICL_DOM) {
00060 GECODE_ES_FAIL(Arithmetic::MaxDom<IntView>::post(home,x0,x1,x2));
00061 } else {
00062 GECODE_ES_FAIL(Arithmetic::MaxBnd<IntView>::post(home,x0,x1,x2));
00063 }
00064 }
00065
00066 void
00067 max(Home home, const IntVarArgs& x, IntVar y,
00068 IntConLevel icl) {
00069 using namespace Int;
00070 if (x.size() == 0)
00071 throw TooFewArguments("Int::max");
00072 if (home.failed()) return;
00073 ViewArray<IntView> xv(home,x);
00074 if (icl == ICL_DOM) {
00075 GECODE_ES_FAIL(Arithmetic::NaryMaxDom<IntView>::post(home,xv,y));
00076 } else {
00077 GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<IntView>::post(home,xv,y));
00078 }
00079 }
00080
00081 void
00082 min(Home home, IntVar x0, IntVar x1, IntVar x2,
00083 IntConLevel icl) {
00084 using namespace Int;
00085 if (home.failed()) return;
00086 MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00087 if (icl == ICL_DOM) {
00088 GECODE_ES_FAIL(Arithmetic::MaxDom<MinusView>::post(home,m0,m1,m2));
00089 } else {
00090 GECODE_ES_FAIL(Arithmetic::MaxBnd<MinusView>::post(home,m0,m1,m2));
00091 }
00092 }
00093
00094 void
00095 min(Home home, const IntVarArgs& x, IntVar y,
00096 IntConLevel icl) {
00097 using namespace Int;
00098 if (x.size() == 0)
00099 throw TooFewArguments("Int::min");
00100 if (home.failed()) return;
00101 ViewArray<MinusView> m(home,x.size());
00102 for (int i=x.size(); i--; )
00103 m[i] = MinusView(x[i]);
00104 MinusView my(y);
00105 if (icl == ICL_DOM) {
00106 GECODE_ES_FAIL(Arithmetic::NaryMaxDom<MinusView>::post(home,m,my));
00107 } else {
00108 GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<MinusView>::post(home,m,my));
00109 }
00110 }
00111
00112
00113 void
00114 argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00115 IntConLevel) {
00116 using namespace Int;
00117 if (x.size() == 0)
00118 throw TooFewArguments("Int::argmax");
00119 if (x.same(home,y))
00120 throw ArgumentSame("Int::argmax");
00121 if (home.failed()) return;
00122
00123 IntView yv(y);
00124 GECODE_ME_FAIL(yv.gq(home,0));
00125 GECODE_ME_FAIL(yv.le(home,x.size()));
00126
00127 IdxViewArray<IntView> ix(home,x.size());
00128 for (int i=x.size(); i--; ) {
00129 ix[i].idx=i; ix[i].view=x[i];
00130 }
00131 if (tiebreak)
00132 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,true>
00133 ::post(home,ix,yv)));
00134 else
00135 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,false>
00136 ::post(home,ix,yv)));
00137 }
00138
00139 void
00140 argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00141 IntConLevel) {
00142 using namespace Int;
00143 if (x.size() == 0)
00144 throw TooFewArguments("Int::argmin");
00145 if (x.same(home,y))
00146 throw ArgumentSame("Int::argmin");
00147 if (home.failed()) return;
00148
00149 IntView yv(y);
00150 GECODE_ME_FAIL(yv.gq(home,0));
00151 GECODE_ME_FAIL(yv.le(home,x.size()));
00152
00153 IdxViewArray<MinusView> ix(home,x.size());
00154 for (int i=x.size(); i--; ) {
00155 ix[i].idx=i; ix[i].view=MinusView(x[i]);
00156 }
00157 if (tiebreak)
00158 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true>
00159 ::post(home,ix,yv)));
00160 else
00161 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false>
00162 ::post(home,ix,yv)));
00163 }
00164
00165
00166 void
00167 mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00168 IntConLevel icl) {
00169 using namespace Int;
00170 if (home.failed()) return;
00171 if (icl == ICL_DOM) {
00172 GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00173 } else {
00174 GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00175 }
00176 }
00177
00178
00179 void
00180 divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00181 IntConLevel) {
00182 using namespace Int;
00183 if (home.failed()) return;
00184
00185 IntVar prod(home, Int::Limits::min, Int::Limits::max);
00186 GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00187 Linear::Term<IntView> t[3];
00188 t[0].a = 1; t[0].x = prod;
00189 t[1].a = 1; t[1].x = x3;
00190 int min, max;
00191 Linear::estimate(t,2,0,min,max);
00192 IntView x0v(x0);
00193 GECODE_ME_FAIL(x0v.gq(home,min));
00194 GECODE_ME_FAIL(x0v.lq(home,max));
00195 t[2].a=-1; t[2].x=x0;
00196 Linear::post(home,t,3,IRT_EQ,0);
00197 if (home.failed()) return;
00198 IntView x1v(x1);
00199 GECODE_ES_FAIL(
00200 Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00201 }
00202
00203 void
00204 div(Home home, IntVar x0, IntVar x1, IntVar x2,
00205 IntConLevel) {
00206 using namespace Int;
00207 if (home.failed()) return;
00208 GECODE_ES_FAIL(
00209 (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00210 }
00211
00212 void
00213 mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00214 IntConLevel icl) {
00215 using namespace Int;
00216 if (home.failed()) return;
00217 IntVar _div(home, Int::Limits::min, Int::Limits::max);
00218 divmod(home, x0, x1, _div, x2, icl);
00219 }
00220
00221 void
00222 sqr(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00223 using namespace Int;
00224 if (home.failed()) return;
00225 Arithmetic::SqrOps ops;
00226 if (icl == ICL_DOM) {
00227 GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00228 ::post(home,x0,x1,ops));
00229 } else {
00230 GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00231 ::post(home,x0,x1,ops));
00232 }
00233 }
00234
00235 void
00236 sqrt(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00237 using namespace Int;
00238 if (home.failed()) return;
00239 Arithmetic::SqrOps ops;
00240 if (icl == ICL_DOM) {
00241 GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00242 ::post(home,x0,x1,ops));
00243 } else {
00244 GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00245 ::post(home,x0,x1,ops));
00246 }
00247 }
00248
00249 void
00250 pow(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00251 using namespace Int;
00252 Limits::nonnegative(n,"Int::pow");
00253 if (home.failed()) return;
00254 if (n == 2) {
00255 sqr(home, x0, x1, icl);
00256 return;
00257 }
00258 Arithmetic::PowOps ops(n);
00259 if (icl == ICL_DOM) {
00260 GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00261 ::post(home,x0,x1,ops));
00262 } else {
00263 GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00264 ::post(home,x0,x1,ops));
00265 }
00266 }
00267
00268 void
00269 nroot(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00270 using namespace Int;
00271 Limits::positive(n,"Int::nroot");
00272 if (home.failed()) return;
00273 if (n == 2) {
00274 sqrt(home, x0, x1, icl);
00275 return;
00276 }
00277 Arithmetic::PowOps ops(n);
00278 if (icl == ICL_DOM) {
00279 GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00280 ::post(home,x0,x1,ops));
00281 } else {
00282 GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00283 ::post(home,x0,x1,ops));
00284 }
00285 }
00286
00287 }
00288
00289