Generated on Thu Mar 22 10:39:39 2012 for Gecode by doxygen 1.6.3

prop.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2011
00008  *
00009  *  Last modified:
00010  *     $Date: 2011-08-22 21:43:31 +0200 (Mon, 22 Aug 2011) $ by $Author: schulte $
00011  *     $Revision: 12335 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <gecode/int/rel.hh>
00039 
00040 namespace Gecode { namespace Int { namespace Member {
00041 
00042   template<class View>
00043   forceinline
00044   Prop<View>::Prop(Home home, ValSet& vs0, ViewArray<View>& x, View y)
00045     : NaryOnePropagator<View,PC_INT_DOM>(home,x,y),
00046       vs(vs0) {}
00047 
00048   template<class View>
00049   forceinline void
00050   Prop<View>::add(Space& home, ValSet& vs, ViewArray<View>& x) {
00051     int n=x.size();
00052     for (int i=n; i--; )
00053       if (x[i].assigned()) {
00054         vs.add(home, x[i].val());
00055         x[i] = x[--n];
00056       }
00057     x.size(n);
00058   }
00059 
00060   template<class View>
00061   forceinline void
00062   Prop<View>::eliminate(Space& home) {
00063     int n=x.size();
00064     for (int i=n; i--; )
00065       if ((rtest_eq_dom(x[i],y) == RT_FALSE) || vs.subset(x[i])) {
00066         // x[i] is different from y or values are contained in vs
00067         x[i].cancel(home, *this, PC_INT_DOM);
00068         x[i] = x[--n]; 
00069       }
00070     x.size(n);
00071   }
00072 
00073   template<class View>
00074   inline ExecStatus
00075   Prop<View>::post(Home home, ViewArray<View>& x, View y) {
00076     if (x.size() == 0)
00077       return ES_FAILED;
00078 
00079     x.unique(home);
00080 
00081     if (x.size() == 1)
00082       return Rel::EqDom<View,View>::post(home,x[0],y);
00083     
00084     if (x.same(home,y))
00085       return ES_OK;
00086 
00087     // Eliminate assigned views and store them into the value set
00088     ValSet vs;
00089     add(home, vs, x);
00090 
00091     if (x.size() == 0) {
00092       ValSet::Ranges vsr(vs);
00093       GECODE_ME_CHECK(y.inter_r(home,vsr,false));
00094       return ES_OK;
00095     }
00096 
00097     (void) new (home) Prop<View>(home, vs, x, y);
00098     return ES_OK;
00099   }
00100     
00101   template<class View>
00102   forceinline ExecStatus
00103   Prop<View>::post(Home home, ValSet& vs, ViewArray<View>& x, View y) {
00104     (void) new (home) Prop<View>(home, vs, x, y);
00105     return ES_OK;
00106   }
00107     
00108   template<class View>
00109   forceinline
00110   Prop<View>::Prop(Space& home, bool share, Prop<View>& p)
00111     : NaryOnePropagator<View,PC_INT_DOM>(home, share, p) {
00112     vs.update(home, share, p.vs);
00113   }
00114 
00115   template<class View>
00116   Propagator*
00117   Prop<View>::copy(Space& home, bool share) {
00118     return new (home) Prop<View>(home, share, *this);
00119   }
00120 
00121   template<class View>
00122   forceinline size_t
00123   Prop<View>::dispose(Space& home) {
00124     vs.dispose(home);
00125     (void) NaryOnePropagator<View,PC_INT_DOM>::dispose(home);
00126     return sizeof(*this);
00127   }
00128 
00129   template<class View>
00130   PropCost 
00131   Prop<View>::cost(const Space&, const ModEventDelta&) const {
00132     return PropCost::linear(PropCost::HI, x.size()+1);
00133   }
00134 
00135   template<class View>
00136   ExecStatus
00137   Prop<View>::propagate(Space& home, const ModEventDelta& med) {
00138     // Add assigned views to value set
00139     if (View::me(med) == ME_INT_VAL)
00140       add(home,vs,x);
00141 
00142     // Eliminate views from x
00143     eliminate(home);
00144     
00145     if (x.size() == 0) {
00146       // y must have values in the value set
00147       ValSet::Ranges vsr(vs);
00148       GECODE_ME_CHECK(y.inter_r(home,vsr,false));
00149       return home.ES_SUBSUMED(*this);
00150     }
00151 
00152     // Constrain y to union of x and value set
00153     Region r(home);
00154 
00155     assert(x.size() > 0);
00156     ValSet::Ranges vsr(vs);
00157     ViewRanges<View> xsr(x[x.size()-1]);
00158     Iter::Ranges::NaryUnion  u(r,vsr,xsr);
00159     for (int i=x.size()-1; i--; ) {
00160       ViewRanges<View> xir(x[i]);
00161       u |= xir;
00162     }
00163 
00164     GECODE_ME_CHECK(y.inter_r(home,u,false));
00165 
00166     // Check whether all values in y are already in the value set
00167     if (vs.subset(y))
00168       return home.ES_SUBSUMED(*this);
00169 
00170     return ES_FIX;
00171   }
00172 
00173 }}}
00174 
00175 // STATISTICS: int-prop