00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/int/rel.hh"
00023
00024 namespace Gecode { namespace Int { namespace Arithmetic {
00025
00026
00027
00028
00029
00030
00031 template <class View>
00032 forceinline
00033 Max<View>::Max(Space* home, View x0, View x1, View x2)
00034 : TernaryPropagator<View,PC_INT_BND>(home,x0,x1,x2) {}
00035
00036 template <class View>
00037 ExecStatus
00038 Max<View>::post(Space* home, View x0, View x1, View x2) {
00039 if (same(x0,x1))
00040 return Rel::EqBnd<View,View>::post(home,x0,x2);
00041 if (same(x0,x2))
00042 return Rel::Lq<View>::post(home,x1,x2);
00043 if (same(x1,x2))
00044 return Rel::Lq<View>::post(home,x0,x2);
00045 (void) new (home) Max<View>(home,x0,x1,x2);
00046 return ES_OK;
00047 }
00048
00049 template <class View>
00050 forceinline
00051 Max<View>::Max(Space* home, bool share, Max<View>& p)
00052 : TernaryPropagator<View,PC_INT_BND>(home,share,p) {}
00053
00054 template <class View>
00055 forceinline
00056 Max<View>::Max(Space* home, bool share, Propagator& p,
00057 View x0, View x1, View x2)
00058 : TernaryPropagator<View,PC_INT_BND>(home,share,p,x0,x1,x2) {}
00059
00060 template <class View>
00061 Actor*
00062 Max<View>::copy(Space* home, bool share) {
00063 return new (home) Max<View>(home,share,*this);
00064 }
00065
00066 template <class View>
00067 ExecStatus
00068 Max<View>::propagate(Space* home) {
00069 bool mod = false;
00070 do {
00071 mod = false;
00072 {
00073 ModEvent me = x2.lq(home,std::max(x0.max(),x1.max()));
00074 if (me_failed(me)) return ES_FAILED;
00075 mod |= me_modified(me);
00076 }
00077 {
00078 ModEvent me = x2.gq(home,std::max(x0.min(),x1.min()));
00079 if (me_failed(me)) return ES_FAILED;
00080 mod |= me_modified(me);
00081 }
00082 {
00083 ModEvent me = x0.lq(home,x2.max());
00084 if (me_failed(me)) return ES_FAILED;
00085 mod |= me_modified(me);
00086 }
00087 {
00088 ModEvent me = x1.lq(home,x2.max());
00089 if (me_failed(me)) return ES_FAILED;
00090 mod |= me_modified(me);
00091 }
00092 } while (mod);
00093 if (x0.max() <= x1.min()) {
00094 GECODE_ES_CHECK((Rel::EqBnd<View,View>::post(home,x1,x2)));
00095 return ES_SUBSUMED;
00096 }
00097 if (x1.max() <= x0.min()) {
00098 GECODE_ES_CHECK((Rel::EqBnd<View,View>::post(home,x0,x2)));
00099 return ES_SUBSUMED;
00100 }
00101 return x0.assigned() && x1.assigned() && x2.assigned() ? ES_SUBSUMED : ES_FIX;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111 template <class View>
00112 forceinline
00113 NaryMax<View>::NaryMax(Space* home, ViewArray<View>& x, View y)
00114 : NaryOnePropagator<View,PC_INT_BND>(home,x,y) {}
00115
00116 template <class View>
00117 ExecStatus
00118 NaryMax<View>::post(Space* home, ViewArray<View>& x, View y) {
00119 assert(x.size() > 0);
00120 x.unique();
00121 if (x.size() == 1)
00122 return Rel::EqBnd<View,View>::post(home,x[0],y);
00123 if (x.size() == 2)
00124 return Max<View>::post(home,x[0],x[1],y);
00125 if (x.same(y)) {
00126
00127 for (int i=x.size(); i--; )
00128 GECODE_ES_CHECK(Rel::Lq<View>::post(home,x[i],y));
00129 } else {
00130 (void) new (home) NaryMax<View>(home,x,y);
00131 }
00132 return ES_OK;
00133 }
00134
00135 template <class View>
00136 forceinline
00137 NaryMax<View>::NaryMax(Space* home, bool share, NaryMax<View>& p)
00138 : NaryOnePropagator<View,PC_INT_BND>(home,share,p) {}
00139
00140 template <class View>
00141 Actor*
00142 NaryMax<View>::copy(Space* home, bool share) {
00143 if (x.size() == 1)
00144 return new (home) Rel::EqBnd<View,View>(home,share,*this,x[0],y);
00145 if (x.size() == 2)
00146 return new (home) Max<View>(home,share,*this,x[0],x[1],y);
00147 return new (home) NaryMax<View>(home,share,*this);
00148 }
00149
00151 enum MaxPropStatus {
00152 MPS_ASSIGNED = 1<<0,
00153 MPS_REMOVED = 1<<1,
00154 MPS_NEW_BOUND = 1<<2
00155 };
00156
00157 template <class View>
00158 ExecStatus
00159 NaryMax<View>::propagate(Space* home) {
00160 rerun:
00161 int maxmax = Limits::Int::int_min-1;
00162 int maxmin = Limits::Int::int_min-1;
00163 for (int i = x.size(); i--; ) {
00164 maxmax = std::max(x[i].max(),maxmax);
00165 maxmin = std::max(x[i].min(),maxmin);
00166 }
00167 GECODE_ME_CHECK(y.lq(home,maxmax));
00168 GECODE_ME_CHECK(y.gq(home,maxmin));
00169 maxmin = y.min();
00170 maxmax = y.max();
00171 int status = MPS_ASSIGNED;
00172 for (int i = x.size(); i--; ) {
00173 ModEvent me = x[i].lq(home,maxmax);
00174 if (me == ME_INT_FAILED)
00175 return ES_FAILED;
00176 if (me_modified(me) && (x[i].max() != maxmax))
00177 status |= MPS_NEW_BOUND;
00178 if (x[i].max() < maxmin) {
00179 x.move_lst(i,home,this,PC_INT_BND);
00180 status |= MPS_REMOVED;
00181 } else if (!x[i].assigned())
00182 status &= ~MPS_ASSIGNED;
00183 }
00184 if (x.size() == 0)
00185 return ES_FAILED;
00186 if ((status & MPS_REMOVED) != 0)
00187 goto rerun;
00188 if (((status & MPS_ASSIGNED) != 0) && y.assigned())
00189 return ES_SUBSUMED;
00190 return ((status & MPS_NEW_BOUND) != 0) ? ES_NOFIX : ES_FIX;
00191 }
00192
00193 }}}
00194
00195
00196