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 #include <gecode/int/arithmetic.hh>
00035
00036 namespace Gecode {
00037
00038 void
00039 abs(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00040 using namespace Int;
00041 GECODE_POST;
00042 if (vbd(ipl) == IPL_DOM) {
00043 GECODE_ES_FAIL(Arithmetic::AbsDom<IntView>::post(home,x0,x1));
00044 } else {
00045 GECODE_ES_FAIL(Arithmetic::AbsBnd<IntView>::post(home,x0,x1));
00046 }
00047 }
00048
00049
00050 void
00051 max(Home home, IntVar x0, IntVar x1, IntVar x2,
00052 IntPropLevel ipl) {
00053 using namespace Int;
00054 GECODE_POST;
00055 if (vbd(ipl) == IPL_DOM) {
00056 GECODE_ES_FAIL(Arithmetic::MaxDom<IntView>::post(home,x0,x1,x2));
00057 } else {
00058 GECODE_ES_FAIL(Arithmetic::MaxBnd<IntView>::post(home,x0,x1,x2));
00059 }
00060 }
00061
00062 void
00063 max(Home home, const IntVarArgs& x, IntVar y,
00064 IntPropLevel ipl) {
00065 using namespace Int;
00066 if (x.size() == 0)
00067 throw TooFewArguments("Int::max");
00068 GECODE_POST;
00069 ViewArray<IntView> xv(home,x);
00070 if (vbd(ipl) == IPL_DOM) {
00071 GECODE_ES_FAIL(Arithmetic::NaryMaxDom<IntView>::post(home,xv,y));
00072 } else {
00073 GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<IntView>::post(home,xv,y));
00074 }
00075 }
00076
00077 void
00078 min(Home home, IntVar x0, IntVar x1, IntVar x2,
00079 IntPropLevel ipl) {
00080 using namespace Int;
00081 GECODE_POST;
00082 MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00083 if (vbd(ipl) == IPL_DOM) {
00084 GECODE_ES_FAIL(Arithmetic::MaxDom<MinusView>::post(home,m0,m1,m2));
00085 } else {
00086 GECODE_ES_FAIL(Arithmetic::MaxBnd<MinusView>::post(home,m0,m1,m2));
00087 }
00088 }
00089
00090 void
00091 min(Home home, const IntVarArgs& x, IntVar y,
00092 IntPropLevel ipl) {
00093 using namespace Int;
00094 if (x.size() == 0)
00095 throw TooFewArguments("Int::min");
00096 GECODE_POST;
00097 ViewArray<MinusView> m(home,x.size());
00098 for (int i=0; i<x.size(); i++)
00099 m[i] = MinusView(x[i]);
00100 MinusView my(y);
00101 if (vbd(ipl) == IPL_DOM) {
00102 GECODE_ES_FAIL(Arithmetic::NaryMaxDom<MinusView>::post(home,m,my));
00103 } else {
00104 GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<MinusView>::post(home,m,my));
00105 }
00106 }
00107
00108
00109 void
00110 argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00111 IntPropLevel) {
00112 using namespace Int;
00113 if (x.size() == 0)
00114 throw TooFewArguments("Int::argmax");
00115 if (same(x,y))
00116 throw ArgumentSame("Int::argmax");
00117 GECODE_POST;
00118
00119 IntView yv(y);
00120 GECODE_ME_FAIL(yv.gq(home,0));
00121 GECODE_ME_FAIL(yv.le(home,x.size()));
00122
00123 IdxViewArray<IntView> ix(home,x.size());
00124 for (int i=0; i<x.size(); i++) {
00125 ix[i].idx=i; ix[i].view=x[i];
00126 }
00127 if (tiebreak)
00128 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,true>
00129 ::post(home,ix,yv)));
00130 else
00131 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,false>
00132 ::post(home,ix,yv)));
00133 }
00134
00135 void
00136 argmax(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00137 IntPropLevel) {
00138 using namespace Int;
00139 Limits::nonnegative(o,"Int::argmax");
00140 if (x.size() == 0)
00141 throw TooFewArguments("Int::argmax");
00142 if (same(x,y))
00143 throw ArgumentSame("Int::argmax");
00144 GECODE_POST;
00145
00146 OffsetView yv(y,-o);
00147 GECODE_ME_FAIL(yv.gq(home,0));
00148 GECODE_ME_FAIL(yv.le(home,x.size()));
00149
00150 IdxViewArray<IntView> ix(home,x.size());
00151 for (int i=0; i<x.size(); i++) {
00152 ix[i].idx=i; ix[i].view=x[i];
00153 }
00154 if (tiebreak)
00155 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,true>
00156 ::post(home,ix,yv)));
00157 else
00158 GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,OffsetView,false>
00159 ::post(home,ix,yv)));
00160 }
00161
00162 void
00163 argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00164 IntPropLevel) {
00165 using namespace Int;
00166 if (x.size() == 0)
00167 throw TooFewArguments("Int::argmin");
00168 if (same(x,y))
00169 throw ArgumentSame("Int::argmin");
00170 GECODE_POST;
00171
00172 IntView yv(y);
00173 GECODE_ME_FAIL(yv.gq(home,0));
00174 GECODE_ME_FAIL(yv.le(home,x.size()));
00175
00176 IdxViewArray<MinusView> ix(home,x.size());
00177 for (int i=0; i<x.size(); i++) {
00178 ix[i].idx=i; ix[i].view=MinusView(x[i]);
00179 }
00180 if (tiebreak)
00181 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true>
00182 ::post(home,ix,yv)));
00183 else
00184 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false>
00185 ::post(home,ix,yv)));
00186 }
00187
00188 void
00189 argmin(Home home, const IntVarArgs& x, int o, IntVar y, bool tiebreak,
00190 IntPropLevel) {
00191 using namespace Int;
00192 Limits::nonnegative(o,"Int::argmin");
00193 if (x.size() == 0)
00194 throw TooFewArguments("Int::argmin");
00195 if (same(x,y))
00196 throw ArgumentSame("Int::argmin");
00197 GECODE_POST;
00198
00199 OffsetView yv(y,-o);
00200 GECODE_ME_FAIL(yv.gq(home,0));
00201 GECODE_ME_FAIL(yv.le(home,x.size()));
00202
00203 IdxViewArray<MinusView> ix(home,x.size());
00204 for (int i=0; i<x.size(); i++) {
00205 ix[i].idx=i; ix[i].view=MinusView(x[i]);
00206 }
00207 if (tiebreak)
00208 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,true>
00209 ::post(home,ix,yv)));
00210 else
00211 GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,OffsetView,false>
00212 ::post(home,ix,yv)));
00213 }
00214
00215
00216 void
00217 mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00218 IntPropLevel ipl) {
00219 using namespace Int;
00220 GECODE_POST;
00221 if (vbd(ipl) == IPL_DOM) {
00222 GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00223 } else {
00224 GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00225 }
00226 }
00227
00228
00229 void
00230 divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00231 IntPropLevel) {
00232 using namespace Int;
00233 GECODE_POST;
00234
00235 IntVar prod(home, Int::Limits::min, Int::Limits::max);
00236 GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00237 Linear::Term<IntView> t[3];
00238 t[0].a = 1; t[0].x = prod;
00239 t[1].a = 1; t[1].x = x3;
00240 int min, max;
00241 Linear::estimate(t,2,0,min,max);
00242 IntView x0v(x0);
00243 GECODE_ME_FAIL(x0v.gq(home,min));
00244 GECODE_ME_FAIL(x0v.lq(home,max));
00245 t[2].a=-1; t[2].x=x0;
00246 Linear::post(home,t,3,IRT_EQ,0,IPL_BND);
00247 if (home.failed()) return;
00248 IntView x1v(x1);
00249 GECODE_ES_FAIL(
00250 Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00251 }
00252
00253 void
00254 div(Home home, IntVar x0, IntVar x1, IntVar x2,
00255 IntPropLevel) {
00256 using namespace Int;
00257 GECODE_POST;
00258 GECODE_ES_FAIL(
00259 (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00260 }
00261
00262 void
00263 mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00264 IntPropLevel ipl) {
00265 using namespace Int;
00266 GECODE_POST;
00267 IntVar _div(home, Int::Limits::min, Int::Limits::max);
00268 divmod(home, x0, x1, _div, x2, ipl);
00269 }
00270
00271 void
00272 sqr(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00273 using namespace Int;
00274 GECODE_POST;
00275 Arithmetic::SqrOps ops;
00276 if (vbd(ipl) == IPL_DOM) {
00277 GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00278 ::post(home,x0,x1,ops));
00279 } else {
00280 GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00281 ::post(home,x0,x1,ops));
00282 }
00283 }
00284
00285 void
00286 sqrt(Home home, IntVar x0, IntVar x1, IntPropLevel ipl) {
00287 using namespace Int;
00288 GECODE_POST;
00289 Arithmetic::SqrOps ops;
00290 if (vbd(ipl) == IPL_DOM) {
00291 GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00292 ::post(home,x0,x1,ops));
00293 } else {
00294 GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00295 ::post(home,x0,x1,ops));
00296 }
00297 }
00298
00299 void
00300 pow(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00301 using namespace Int;
00302 Limits::nonnegative(n,"Int::pow");
00303 GECODE_POST;
00304 if (n == 2) {
00305 sqr(home, x0, x1, ipl);
00306 return;
00307 }
00308 Arithmetic::PowOps ops(n);
00309 if (vbd(ipl) == IPL_DOM) {
00310 GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00311 ::post(home,x0,x1,ops));
00312 } else {
00313 GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00314 ::post(home,x0,x1,ops));
00315 }
00316 }
00317
00318 void
00319 nroot(Home home, IntVar x0, int n, IntVar x1, IntPropLevel ipl) {
00320 using namespace Int;
00321 Limits::positive(n,"Int::nroot");
00322 GECODE_POST;
00323 if (n == 2) {
00324 sqrt(home, x0, x1, ipl);
00325 return;
00326 }
00327 Arithmetic::PowOps ops(n);
00328 if (vbd(ipl) == IPL_DOM) {
00329 GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00330 ::post(home,x0,x1,ops));
00331 } else {
00332 GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00333 ::post(home,x0,x1,ops));
00334 }
00335 }
00336
00337 }
00338
00339