00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace Bool {
00023
00024 template <class BVA, class BVB, class BVC>
00025 forceinline
00026 And<BVA,BVB,BVC>::And(Space* home, BVA b0, BVB b1, BVC b2)
00027 : BoolTernary<BVA,BVB,BVC>(home,b0,b1,b2) {}
00028
00029 template <class BVA, class BVB, class BVC>
00030 forceinline
00031 And<BVA,BVB,BVC>::And(Space* home, bool share, And<BVA,BVB,BVC>& p)
00032 : BoolTernary<BVA,BVB,BVC>(home,share,p) {}
00033
00034 template <class BVA, class BVB, class BVC>
00035 forceinline
00036 And<BVA,BVB,BVC>::And(Space* home, bool share, Propagator& p,
00037 BVA b0, BVB b1, BVC b2)
00038 : BoolTernary<BVA,BVB,BVC>(home,share,p,b0,b1,b2) {}
00039
00040 template <class BVA, class BVB, class BVC>
00041 forceinline ExecStatus
00042 And<BVA,BVB,BVC>::post(Space* home, BVA b0, BVB b1, BVC b2) {
00043 switch (bool_test(b0,b1)) {
00044 case BT_SAME:
00045 return Eq<BVA,BVC>::post(home,b0,b2);
00046 case BT_COMP:
00047 GECODE_ME_CHECK(b2.t_zero(home));
00048 break;
00049 case BT_NONE:
00050 if (b0.zero() || b1.zero()) {
00051 GECODE_ME_CHECK(b2.t_zero(home));
00052 } else if (b0.one()) {
00053 return Eq<BVB,BVC>::post(home,b1,b2);
00054 } else if (b1.one()) {
00055 return Eq<BVA,BVC>::post(home,b0,b2);
00056 } else if (b2.one()) {
00057 assert(b0.none() && b1.none());
00058 b0.t_one_none(home); b1.t_one_none(home);
00059 } else {
00060 (void) new (home) And<BVA,BVB,BVC>(home,b0,b1,b2);
00061 }
00062 break;
00063 }
00064 return ES_OK;
00065 }
00066
00067 template <class BVA, class BVB, class BVC>
00068 Actor*
00069 And<BVA,BVB,BVC>::copy(Space* home, bool share) {
00070 return new (home) And<BVA,BVB,BVC>(home,share,*this);
00071 }
00072
00073 template <class BVA, class BVB, class BVC>
00074 ExecStatus
00075 And<BVA,BVB,BVC>::propagate(Space* home) {
00076 if (x0.zero() || x1.zero()) {
00077 GECODE_ES_CHECK(x2.t_zero(home));
00078 } else if (x2.one()) {
00079 GECODE_ES_CHECK(x0.t_one(home));
00080 GECODE_ES_CHECK(x1.t_one(home));
00081 } else if (x2.zero()) {
00082 if (x0.one()) {
00083 GECODE_ES_CHECK(x1.t_zero(home));
00084 } else if (x1.one()) {
00085 GECODE_ES_CHECK(x0.t_zero(home));
00086 } else {
00087 return ES_FIX;
00088 }
00089 } else if (x0.one() && x1.one()) {
00090 GECODE_ES_CHECK(x2.t_one(home));
00091 } else {
00092 return ES_FIX;
00093 }
00094 return ES_SUBSUMED;
00095 }
00096
00097
00098 template<class View>
00099 forceinline
00100 NaryAnd<View>::NaryAnd(Space* home, ViewArray<View>& b, View c)
00101 : NaryOnePropagator<View,PC_INT_VAL>(home,b,c) {}
00102
00103 template<class View>
00104 forceinline
00105 NaryAnd<View>::NaryAnd(Space* home, bool share, NaryAnd<View>& p)
00106 : NaryOnePropagator<View,PC_INT_VAL>(home,share,p) {}
00107
00108 template<class View>
00109 forceinline ExecStatus
00110 NaryAnd<View>::post(Space* home, ViewArray<View>& b, View c) {
00111 if (b.size() > 0) {
00112 b.unique();
00113 if (b.size() == 1)
00114 return Eq<View,View>::post(home,b[0],c);
00115 if (b.size() == 2)
00116 return And<View,View,View>::post(home,b[0],b[1],c);
00117 (void) new (home) NaryAnd(home,b,c);
00118 }
00119 return ES_OK;
00120 }
00121
00122 template<class View>
00123 Actor*
00124 NaryAnd<View>::copy(Space* home, bool share) {
00125 if (x.size() == 1)
00126 return new (home) Eq<View,View>(home,share,*this,
00127 x[0],y);
00128 if (x.size() == 2)
00129 return new (home) And<View,View,View>(home,share,*this,
00130 x[0],x[1],y);
00131 return new (home) NaryAnd<View>(home,share,*this);
00132 }
00133
00134 template<class View>
00135 ExecStatus
00136 NaryAnd<View>::propagate(Space* home) {
00137 if (y.one()) {
00138 for (int i = x.size(); i--; )
00139 GECODE_ME_CHECK(x[i].t_one(home));
00140 return ES_SUBSUMED;
00141 }
00142 if (y.zero()) {
00143 bool none = false;
00144 for (int i = x.size(); i--; ) {
00145 if (x[i].zero())
00146 return ES_SUBSUMED;
00147 if (!x[i].one())
00148 none = true;
00149 }
00150 return none ? ES_FIX : ES_FAILED;
00151 }
00152 for (int i = x.size(); i--; ) {
00153 if (x[i].zero()) {
00154 y.t_zero_none(home);
00155 return ES_SUBSUMED;
00156 }
00157 if (x[i].one())
00158 x.move_lst(i);
00159 }
00160 if (x.size() == 0) {
00161 y.t_one_none(home);
00162 return ES_SUBSUMED;
00163 }
00164 return ES_FIX;
00165 }
00166
00167 }}}
00168
00169
00170