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 ExecStatus
00036 And<BVA,BVB,BVC>::post(Space* home, BVA b0, BVB b1, BVC b2) {
00037 switch (bool_test(b0,b1)) {
00038 case BT_SAME:
00039 return Eq<BVA,BVC>::post(home,b0,b2);
00040 case BT_COMP:
00041 GECODE_ME_CHECK(b2.t_zero(home));
00042 break;
00043 case BT_NONE:
00044 if (b0.zero() || b1.zero()) {
00045 GECODE_ME_CHECK(b2.t_zero(home));
00046 } else if (b0.one()) {
00047 return Eq<BVB,BVC>::post(home,b1,b2);
00048 } else if (b1.one()) {
00049 return Eq<BVA,BVC>::post(home,b0,b2);
00050 } else if (b2.one()) {
00051 assert(b0.none() && b1.none());
00052 b0.t_one_none(home); b1.t_one_none(home);
00053 } else {
00054 (void) new (home) And<BVA,BVB,BVC>(home,b0,b1,b2);
00055 }
00056 break;
00057 }
00058 return ES_OK;
00059 }
00060
00061 template <class BVA, class BVB, class BVC>
00062 Actor*
00063 And<BVA,BVB,BVC>::copy(Space* home, bool share) {
00064 return new (home) And<BVA,BVB,BVC>(home,share,*this);
00065 }
00066
00067 template <class BVA, class BVB, class BVC>
00068 ExecStatus
00069 And<BVA,BVB,BVC>::propagate(Space* home) {
00070 if (x0.zero() || x1.zero()) {
00071 GECODE_ES_CHECK(x2.t_zero(home));
00072 } else if (x2.one()) {
00073 GECODE_ES_CHECK(x0.t_one(home));
00074 GECODE_ES_CHECK(x1.t_one(home));
00075 } else if (x2.zero()) {
00076 if (x0.one()) {
00077 GECODE_ES_CHECK(x1.t_zero(home));
00078 } else if (x1.one()) {
00079 GECODE_ES_CHECK(x0.t_zero(home));
00080 } else {
00081 return ES_FIX;
00082 }
00083 } else if (x0.one() && x1.one()) {
00084 GECODE_ES_CHECK(x2.t_one(home));
00085 } else {
00086 return ES_FIX;
00087 }
00088 return ES_SUBSUMED;
00089 }
00090
00091
00092 template<class View>
00093 forceinline
00094 NaryAnd<View>::NaryAnd(Space* home, ViewArray<View>& b, View c)
00095 : NaryOnePropagator<View,PC_INT_VAL>(home,b,c) {}
00096
00097 template<class View>
00098 forceinline
00099 NaryAnd<View>::NaryAnd(Space* home, bool share, NaryAnd<View>& p)
00100 : NaryOnePropagator<View,PC_INT_VAL>(home,share,p) {}
00101
00102 template<class View>
00103 forceinline ExecStatus
00104 NaryAnd<View>::post(Space* home, ViewArray<View>& b, View c) {
00105 if (b.size() > 0) {
00106 b.unique();
00107 if (b.size() == 1)
00108 return Eq<View,View>::post(home,b[0],c);
00109 if (b.size() == 2)
00110 return And<View,View,View>::post(home,b[0],b[1],c);
00111 (void) new (home) NaryAnd(home,b,c);
00112 }
00113 return ES_OK;
00114 }
00115
00116 template<class View>
00117 Actor*
00118 NaryAnd<View>::copy(Space* home, bool share) {
00119 return new (home) NaryAnd<View>(home,share,*this);
00120 }
00121
00122 template<class View>
00123 ExecStatus
00124 NaryAnd<View>::propagate(Space* home) {
00125 if (y.one()) {
00126 for (int i = x.size(); i--; )
00127 GECODE_ME_CHECK(x[i].t_one(home));
00128 return ES_SUBSUMED;
00129 }
00130 if (y.zero()) {
00131 bool none = false;
00132 for (int i = x.size(); i--; ) {
00133 if (x[i].zero())
00134 return ES_SUBSUMED;
00135 if (!x[i].one())
00136 none = true;
00137 }
00138 return none ? ES_FIX : ES_FAILED;
00139 }
00140 for (int i = x.size(); i--; ) {
00141 if (x[i].zero()) {
00142 y.t_zero_none(home);
00143 return ES_SUBSUMED;
00144 }
00145 if (x[i].one())
00146 x.move_lst(i);
00147 }
00148 if (x.size() == 0) {
00149 y.t_one_none(home);
00150 return ES_SUBSUMED;
00151 }
00152 return ES_FIX;
00153 }
00154
00155 }}}
00156
00157
00158