abs.icc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <algorithm>
00023
00024 namespace Gecode { namespace Int { namespace Arithmetic {
00025
00026 template <class View>
00027 forceinline
00028 Abs<View>::Abs(Space* home, View x0, View x1)
00029 : BinaryPropagator<View,PC_INT_BND>(home,x0,x1) {}
00030
00031 template <class View>
00032 ExecStatus
00033 Abs<View>::post(Space* home, View x0, View x1) {
00034 GECODE_ME_CHECK(x1.gq(home,0));
00035 if (!same(x0,x1)) {
00036 (void) new (home) Abs<View>(home,x0,x1);
00037 }
00038 return ES_OK;
00039 }
00040
00041
00042 template <class View>
00043 forceinline
00044 Abs<View>::Abs(Space* home, bool share, Abs<View>& p)
00045 : BinaryPropagator<View,PC_INT_BND>(home,share,p) {}
00046
00047 template <class View>
00048 Actor*
00049 Abs<View>::copy(Space* home,bool share) {
00050 return new (home) Abs<View>(home,share,*this);
00051 }
00052
00053 #define GECODE_CM(TELL) \
00054 { \
00055 ModEvent me = (TELL); \
00056 if (me_failed(me)) return ES_FAILED; \
00057 if (me_modified(me)) mod = true; \
00058 }
00059
00060 template <class View>
00061 ExecStatus
00062 Abs<View>::propagate(Space* home) {
00063 if (x0.min() >= 0) {
00064 GECODE_ES_CHECK(Rel::EqBnd<View>::post(home,x0,x1));
00065 return ES_SUBSUMED;
00066 }
00067 if (x0.max() <= 0) {
00068 return (Linear::EqBin<int,View,View>::post(home,x0,x1,0) == ES_FAILED)
00069 ? ES_FAILED : ES_SUBSUMED;
00070 }
00071 bool mod = false;
00072 do {
00073 mod = false;
00074 GECODE_CM(x1.lq(home,std::max(x0.max(),-x0.min())));
00075 GECODE_CM(x0.lq(home,x1.max()));
00076 GECODE_CM(x0.gq(home,-x1.max()));
00077 } while (mod);
00078 if (x0.assigned()) {
00079 GECODE_ME_CHECK(x1.eq(home,(x0.val() < 0) ? -x0.val() : x0.val()));
00080 return ES_SUBSUMED;
00081 }
00082 return ES_FIX;
00083 }
00084
00085 #undef GECODE_CM
00086
00087 }}}
00088
00089
00090