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