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