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/rel.hh>
00035
00036 namespace Gecode { namespace Int { namespace Dom {
00037
00038 template<class View, ReifyMode rm>
00039 forceinline
00040 ReRange<View,rm>::ReRange(Home home, View x, int min0, int max0, BoolView b)
00041 : ReUnaryPropagator<View,PC_INT_DOM,BoolView>(home,x,b),
00042 min(min0), max(max0) {}
00043
00044 template<class View, ReifyMode rm>
00045 ExecStatus
00046 ReRange<View,rm>::post(Home home, View x, int min, int max, BoolView b) {
00047 if (min == max) {
00048 return Rel::ReEqDomInt<View,BoolView,rm>::post(home,x,min,b);
00049 } else if ((min > max) || (max < x.min()) || (min > x.max())) {
00050 if (rm == RM_PMI)
00051 return ES_OK;
00052 GECODE_ME_CHECK(b.zero(home));
00053 } else if ((min <= x.min()) && (x.max() <= max)) {
00054 if (rm == RM_IMP)
00055 return ES_OK;
00056 GECODE_ME_CHECK(b.one(home));
00057 } else if (b.one()) {
00058 if (rm == RM_PMI)
00059 return ES_OK;
00060 GECODE_ME_CHECK(x.gq(home,min));
00061 GECODE_ME_CHECK(x.lq(home,max));
00062 } else if (b.zero()) {
00063 if (rm == RM_IMP)
00064 return ES_OK;
00065 Iter::Ranges::Singleton r(min,max);
00066 GECODE_ME_CHECK(x.minus_r(home,r,false));
00067 } else {
00068 (void) new (home) ReRange<View,rm>(home,x,min,max,b);
00069 }
00070 return ES_OK;
00071 }
00072
00073
00074 template<class View, ReifyMode rm>
00075 forceinline
00076 ReRange<View,rm>::ReRange(Space& home, ReRange& p)
00077 : ReUnaryPropagator<View,PC_INT_DOM,BoolView>(home,p),
00078 min(p.min), max(p.max) {}
00079
00080 template<class View, ReifyMode rm>
00081 Actor*
00082 ReRange<View,rm>::copy(Space& home) {
00083 return new (home) ReRange<View,rm>(home,*this);
00084 }
00085
00086 template<class View, ReifyMode rm>
00087 ExecStatus
00088 ReRange<View,rm>::propagate(Space& home, const ModEventDelta&) {
00089 if (b.one()) {
00090 if (rm != RM_PMI) {
00091 GECODE_ME_CHECK(x0.gq(home,min));
00092 GECODE_ME_CHECK(x0.lq(home,max));
00093 }
00094 return home.ES_SUBSUMED(*this);
00095 } else if (b.zero()) {
00096 if (rm != RM_IMP) {
00097 Iter::Ranges::Singleton r(min,max);
00098 GECODE_ME_CHECK(x0.minus_r(home,r,false));
00099 }
00100 return home.ES_SUBSUMED(*this);
00101 } else if ((x0.max() <= max) && (x0.min() >= min)) {
00102 if (rm != RM_IMP)
00103 GECODE_ME_CHECK(b.one_none(home));
00104 return home.ES_SUBSUMED(*this);
00105 } else if ((x0.max() < min) || (x0.min() > max)) {
00106 if (rm != RM_PMI)
00107 GECODE_ME_CHECK(b.zero_none(home));
00108 return home.ES_SUBSUMED(*this);
00109 } else if (!x0.range()) {
00110 ViewRanges<View> i_x(x0);
00111 Iter::Ranges::Singleton i_mm(min,max);
00112
00113 switch (Iter::Ranges::compare(i_x,i_mm)) {
00114 case Iter::Ranges::CS_SUBSET:
00115 if (rm != RM_IMP)
00116 GECODE_ME_CHECK(b.one_none(home));
00117 return home.ES_SUBSUMED(*this);
00118 case Iter::Ranges::CS_DISJOINT:
00119 if (rm != RM_PMI)
00120 GECODE_ME_CHECK(b.zero_none(home));
00121 return home.ES_SUBSUMED(*this);
00122 case Iter::Ranges::CS_NONE:
00123 break;
00124 default: GECODE_NEVER;
00125 }
00126 return ES_FIX;
00127 }
00128 return ES_FIX;
00129 }
00130
00131 }}}
00132
00133
00134