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
00039
00040
00041
00042
00043
00044 namespace Gecode { namespace Set { namespace RelOp {
00045
00046 template<class View0, class View1, class View2>
00047 Actor*
00048 SubOfUnion<View0,View1,View2>::copy(Space& home, bool share) {
00049 return new (home) SubOfUnion(home,share,*this);
00050 }
00051
00052 template<class View0, class View1, class View2>
00053 ExecStatus
00054 SubOfUnion<View0,View1,View2>::propagate(Space& home, const ModEventDelta& med) {
00055
00056 bool allassigned = x0.assigned() && x1.assigned() && x2.assigned();
00057
00058 ModEvent me0 = View0::me(med);
00059 ModEvent me1 = View1::me(med);
00060 ModEvent me2 = View2::me(med);
00061
00062 bool modified=false;
00063
00064 do {
00065
00066 if (modified || Rel::testSetEventUB(me0,me1))
00067 {
00068 LubRanges<View0> ub0(x0);
00069 LubRanges<View1> ub1(x1);
00070 Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u(ub0,ub1);
00071 GECODE_ME_CHECK(x2.intersectI(home,u));
00072 }
00073
00074
00075
00076 if (modified || Rel::testSetEventAnyB(me0,me1,me2)) {
00077 {
00078 modified = false;
00079 GlbRanges<View2> lb2(x2);
00080 LubRanges<View0> ub0(x0);
00081 Iter::Ranges::Diff<GlbRanges<View2>, LubRanges<View0> >
00082 diff(lb2,ub0);
00083 GECODE_ME_CHECK_MODIFIED(modified, x1.includeI(home,diff));
00084 }
00085 {
00086 GlbRanges<View2> lb2(x2);
00087 LubRanges<View1> ub1(x1);
00088 Iter::Ranges::Diff<GlbRanges<View2>, LubRanges<View1> >
00089 diff(lb2,ub1);
00090 GECODE_ME_CHECK_MODIFIED(modified, x0.includeI(home,diff));
00091 }
00092 } else {
00093 modified = false;
00094 }
00095
00096
00097 if (modified ||
00098 Rel::testSetEventCard(me0,me1,me2) ||
00099 Rel::testSetEventLB(me0,me1)
00100 ) {
00101 GlbRanges<View0> lb0c(x0);
00102 GlbRanges<View1> lb1c(x1);
00103 Iter::Ranges::Inter<GlbRanges<View0>, GlbRanges<View1> >
00104 inter(lb0c,lb1c);
00105
00106 unsigned int m = Iter::Ranges::size(inter);
00107
00108 if (m < x0.cardMax()+x1.cardMax()) {
00109 GECODE_ME_CHECK_MODIFIED(modified,
00110 x2.cardMax( home,
00111 x0.cardMax()+x1.cardMax() - m ) );
00112 }
00113 if (m + x2.cardMin() > x1.cardMax()) {
00114 GECODE_ME_CHECK_MODIFIED(modified,
00115 x0.cardMin( home,
00116 m+x2.cardMin()-x1.cardMax() ) );
00117 }
00118 if (m + x2.cardMin() > x0.cardMax()) {
00119 GECODE_ME_CHECK_MODIFIED(modified,
00120 x1.cardMin( home,
00121 m+x2.cardMin()-x0.cardMax() ) );
00122 }
00123 }
00124
00125 } while (modified);
00126
00127 if (shared(x0,x1,x2)) {
00128 if (allassigned) {
00129 return home.ES_SUBSUMED(*this);
00130 } else {
00131 return ES_NOFIX;
00132 }
00133 } else {
00134 if (x0.assigned() + x1.assigned() + x2.assigned() >= 2) {
00135 return home.ES_SUBSUMED(*this);
00136 } else {
00137 return ES_FIX;
00138 }
00139 }
00140
00141 }
00142
00143 template<class View0, class View1, class View2>
00144 forceinline
00145 SubOfUnion<View0,View1,View2>::SubOfUnion(Home home, View0 y0,
00146 View1 y1, View2 y2)
00147 : MixTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00148 View2,PC_SET_ANY>(home,y0,y1,y2) {}
00149
00150 template<class View0, class View1, class View2>
00151 forceinline
00152 SubOfUnion<View0,View1,View2>::SubOfUnion
00153 (Space& home, bool share, SubOfUnion<View0,View1,View2>& p)
00154 : MixTernaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY,
00155 View2,PC_SET_ANY>(home,share,p) {}
00156
00157 template<class View0, class View1, class View2>
00158 ExecStatus SubOfUnion<View0,View1,View2>::post
00159 (Home home, View0 x0, View1 x1, View2 x2) {
00160 (void) new (home) SubOfUnion<View0,View1,View2>(home,x0, x1, x2);
00161 return ES_OK;
00162 }
00163
00164 }}}
00165
00166