Generated on Wed Nov 1 15:04:46 2006 for Gecode by doxygen 1.4.5

subofunion.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Gabor Szokoli <szokoli@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2004
00011  *     Christian Schulte, 2004
00012  *     Gabor Szokoli, 2004
00013  *
00014  *  Last modified:
00015  *     $Date: 2006-08-25 17:31:32 +0200 (Fri, 25 Aug 2006) $ by $Author: tack $
00016  *     $Revision: 3573 $
00017  *
00018  *  This file is part of Gecode, the generic constraint
00019  *  development environment:
00020  *     http://www.gecode.org
00021  *
00022  *  See the file "LICENSE" for information on usage and
00023  *  redistribution of this file, and for a
00024  *     DISCLAIMER OF ALL WARRANTIES.
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       // lub(x2) <= lub(x0) u lub(x1)
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       // x1 <= glb(x2)-lub(x0)
00059       // x0 <= glb(x2)-lub(x1)
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       // cardinality propagation
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 // STATISTICS: set-prop