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 <algorithm>
00039
00040 namespace Gecode { namespace Int { namespace Rel {
00041
00042
00043
00044
00045
00046 template<class V0, class V1>
00047 forceinline
00048 Nq<V0,V1>::Nq(Home home, V0 x0, V1 x1)
00049 : MixBinaryPropagator<V0,PC_INT_VAL,V1,PC_INT_VAL>(home,x0,x1) {}
00050
00051 template<class V0, class V1>
00052 ExecStatus
00053 Nq<V0,V1>::post(Home home, V0 x0, V1 x1){
00054 if (x0.assigned()) {
00055 GECODE_ME_CHECK(x1.nq(home,x0.val()));
00056 } else if (x1.assigned()) {
00057 GECODE_ME_CHECK(x0.nq(home,x1.val()));
00058 } else if (same(x0,x1)) {
00059 return ES_FAILED;
00060 } else {
00061 (void) new (home) Nq<V0,V1>(home,x0,x1);
00062 }
00063 return ES_OK;
00064 }
00065
00066 template<class V0, class V1>
00067 forceinline
00068 Nq<V0,V1>::Nq(Space& home, bool share, Nq<V0,V1>& p)
00069 : MixBinaryPropagator<V0,PC_INT_VAL,V1,PC_INT_VAL>(home,share,p) {}
00070
00071 template<class V0, class V1>
00072 Actor*
00073 Nq<V0,V1>::copy(Space& home, bool share) {
00074 return new (home) Nq<V0,V1>(home,share,*this);
00075 }
00076
00077 template<class V0, class V1>
00078 PropCost
00079 Nq<V0,V1>::cost(const Space&, const ModEventDelta&) const {
00080 return PropCost::unary(PropCost::LO);
00081 }
00082
00083 template<class V0, class V1>
00084 ExecStatus
00085 Nq<V0,V1>::propagate(Space& home, const ModEventDelta&) {
00086 if (x0.assigned()) {
00087 GECODE_ME_CHECK(x1.nq(home,x0.val()));
00088 } else {
00089 GECODE_ME_CHECK(x0.nq(home,x1.val()));
00090 }
00091 return home.ES_SUBSUMED(*this);
00092 }
00093
00094
00095
00096
00097
00098 template<class View>
00099 forceinline
00100 NaryNq<View>::NaryNq(Home home, ViewArray<View>& x)
00101 : NaryPropagator<View,PC_INT_VAL>(home,x) {}
00102
00103 template<class View>
00104 PropCost
00105 NaryNq<View>::cost(const Space&, const ModEventDelta&) const {
00106 return PropCost::linear(PropCost::LO,x.size());
00107 }
00108
00109 template<class View>
00110 forceinline
00111 NaryNq<View>::NaryNq(Space& home, bool share, NaryNq<View>& p)
00112 : NaryPropagator<View,PC_INT_VAL>(home,share,p) {}
00113
00114 template<class View>
00115 Actor*
00116 NaryNq<View>::copy(Space& home, bool share) {
00117 return new (home) NaryNq<View>(home,share,*this);
00118 }
00119
00120 template<class View>
00121 inline ExecStatus
00122 NaryNq<View>::post(Home home, ViewArray<View>& x) {
00123 x.unique(home);
00124
00125 int n = x.size();
00126 if (n <= 1)
00127 return ES_FAILED;
00128 for (int i=n; i--; )
00129 if (x[i].assigned()) {
00130 std::swap(x[0],x[i]);
00131 break;
00132 }
00133 if (x[0].assigned()) {
00134 int v = x[0].val();
00135
00136 for (int i=n-1; i>0; i--)
00137 if (!x[i].in(v)) {
00138 return ES_OK;
00139 } else if (x[i].assigned()) {
00140 assert(x[i].val() == v);
00141 x[i]=x[--n];
00142 }
00143 x.size(n);
00144 }
00145 if (n == 1)
00146 return ES_FAILED;
00147 if (n == 2)
00148 return Nq<View,View>::post(home,x[0],x[1]);
00149 (void) new (home) NaryNq(home,x);
00150 return ES_OK;
00151 }
00152
00153 template<class View>
00154 forceinline size_t
00155 NaryNq<View>::dispose(Space& home) {
00156 (void) NaryPropagator<View,PC_INT_VAL>::dispose(home);
00157 return sizeof(*this);
00158 }
00159
00160 template<class View>
00161 ExecStatus
00162 NaryNq<View>::propagate(Space& home, const ModEventDelta&) {
00163
00164 if (!x[0].assigned()) {
00165
00166 for (int i=1; true; i++)
00167 if (x[i].assigned()) {
00168 std::swap(x[0],x[i]);
00169 break;
00170 }
00171 }
00172 int v = x[0].val();
00173 int n = x.size();
00174 for (int i=n-1; i>0; i--)
00175 if (!x[i].in(v)) {
00176 x.size(n);
00177 return home.ES_SUBSUMED(*this);
00178 } else if (x[i].assigned()) {
00179 assert(x[i].val() == v);
00180 x[i] = x[--n];
00181 }
00182 x.size(n);
00183 if (n == 1)
00184 return ES_FAILED;
00185 if (n == 2) {
00186 GECODE_ME_CHECK(x[1].nq(home,v));
00187 return home.ES_SUBSUMED(*this);
00188 }
00189 return ES_FIX;
00190 }
00191
00192
00193
00194 }}}
00195
00196