wait.hh
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, 2009 00008 * 00009 * Last modified: 00010 * $Date: 2010-03-03 17:32:21 +0100 (Wed, 03 Mar 2010) $ by $Author: schulte $ 00011 * $Revision: 10364 $ 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 #ifndef __GECODE_KERNEL_WAIT_HH__ 00039 #define __GECODE_KERNEL_WAIT_HH__ 00040 00041 #include <gecode/kernel.hh> 00042 00043 namespace Gecode { namespace Kernel { 00044 00051 template<class View> 00052 class UnaryWait : public Propagator { 00053 protected: 00055 View x; 00057 void (*c)(Space&); 00059 UnaryWait(Space& home, View x, void (*c0)(Space&)); 00061 UnaryWait(Space& home, bool shared, UnaryWait& p); 00062 public: 00064 virtual Actor* copy(Space& home, bool share); 00066 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 00068 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 00070 static ExecStatus post(Space& home, View x, void (*c)(Space&)); 00072 virtual size_t dispose(Space& home); 00073 }; 00074 00081 template<class View> 00082 class NaryWait : public Propagator { 00083 protected: 00085 ViewArray<View> x; 00087 void (*c)(Space&); 00089 NaryWait(Space& home, ViewArray<View>& x, void (*c0)(Space&)); 00091 NaryWait(Space& home, bool shared, NaryWait& p); 00092 public: 00094 virtual Actor* copy(Space& home, bool share); 00096 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 00098 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 00100 static ExecStatus post(Space& home, ViewArray<View>& x, void (*c)(Space&)); 00102 virtual size_t dispose(Space& home); 00103 }; 00104 00105 00106 /* 00107 * Wait propagator for single view 00108 * 00109 */ 00110 template<class View> 00111 forceinline 00112 UnaryWait<View>::UnaryWait(Space& home, View x0, void (*c0)(Space&)) 00113 : Propagator(home), x(x0), c(c0) { 00114 x.subscribe(home,*this,PC_GEN_ASSIGNED); 00115 } 00116 template<class View> 00117 forceinline 00118 UnaryWait<View>::UnaryWait(Space& home, bool shared, UnaryWait& p) 00119 : Propagator(home,shared,p), c(p.c) { 00120 x.update(home,shared,p.x); 00121 } 00122 template<class View> 00123 Actor* 00124 UnaryWait<View>::copy(Space& home, bool share) { 00125 return new (home) UnaryWait<View>(home,share,*this); 00126 } 00127 template<class View> 00128 PropCost 00129 UnaryWait<View>::cost(const Space&, const ModEventDelta&) const { 00130 return PropCost::unary(PropCost::LO); 00131 } 00132 template<class View> 00133 ExecStatus 00134 UnaryWait<View>::propagate(Space& home, const ModEventDelta&) { 00135 assert(x.assigned()); 00136 c(home); 00137 return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this); 00138 } 00139 template<class View> 00140 ExecStatus 00141 UnaryWait<View>::post(Space& home, View x, void (*c)(Space&)) { 00142 if (x.assigned()) { 00143 c(home); 00144 return home.failed() ? ES_FAILED : ES_OK; 00145 } else { 00146 (void) new (home) UnaryWait<View>(home,x,c); 00147 return ES_OK; 00148 } 00149 } 00150 template<class View> 00151 size_t 00152 UnaryWait<View>::dispose(Space& home) { 00153 x.cancel(home,*this,PC_GEN_ASSIGNED); 00154 (void) Propagator::dispose(home); 00155 return sizeof(*this); 00156 } 00157 00158 00159 /* 00160 * Wait propagator for several views 00161 * 00162 */ 00163 template<class View> 00164 forceinline 00165 NaryWait<View>::NaryWait(Space& home, ViewArray<View>& x0, 00166 void (*c0)(Space&)) 00167 : Propagator(home), x(x0), c(c0) { 00168 assert(!x[0].assigned()); 00169 x[0].subscribe(home,*this,PC_GEN_ASSIGNED); 00170 } 00171 template<class View> 00172 forceinline 00173 NaryWait<View>::NaryWait(Space& home, bool shared, NaryWait& p) 00174 : Propagator(home,shared,p), c(p.c) { 00175 x.update(home,shared,p.x); 00176 } 00177 template<class View> 00178 Actor* 00179 NaryWait<View>::copy(Space& home, bool share) { 00180 assert(!x[0].assigned()); 00181 for (int i=x.size()-1; i>0; i--) 00182 if (x[i].assigned()) 00183 x.move_lst(i); 00184 assert(x.size() > 0); 00185 return new (home) NaryWait<View>(home,share,*this); 00186 } 00187 template<class View> 00188 PropCost 00189 NaryWait<View>::cost(const Space&, const ModEventDelta&) const { 00190 return PropCost::unary(PropCost::HI); 00191 } 00192 template<class View> 00193 ExecStatus 00194 NaryWait<View>::propagate(Space& home, const ModEventDelta& ) { 00195 assert(x[0].assigned()); 00196 for (int i=x.size()-1; i>0; i--) 00197 if (x[i].assigned()) 00198 x.move_lst(i); 00199 assert(x.size() > 0); 00200 if (x.size() == 1) { 00201 x.size(0); 00202 c(home); 00203 return home.failed() ? ES_FAILED : home.ES_SUBSUMED(*this); 00204 } else { 00205 // Create new subscription 00206 x.move_lst(0); 00207 assert(!x[0].assigned()); 00208 x[0].subscribe(home,*this,PC_GEN_ASSIGNED,false); 00209 return ES_OK; 00210 } 00211 } 00212 template<class View> 00213 ExecStatus 00214 NaryWait<View>::post(Space& home, ViewArray<View>& x, void (*c)(Space&)) { 00215 for (int i=x.size(); i--; ) 00216 if (x[i].assigned()) 00217 x.move_lst(i); 00218 if (x.size() == 0) { 00219 c(home); 00220 return home.failed() ? ES_FAILED : ES_OK; 00221 } else { 00222 x.unique(home); 00223 if (x.size() == 1) { 00224 return UnaryWait<View>::post(home,x[0],c); 00225 } else { 00226 (void) new (home) NaryWait<View>(home,x,c); 00227 return ES_OK; 00228 } 00229 } 00230 } 00231 template<class View> 00232 size_t 00233 NaryWait<View>::dispose(Space& home) { 00234 if (x.size() > 0) 00235 x[0].cancel(home,*this,PC_GEN_ASSIGNED); 00236 (void) Propagator::dispose(home); 00237 return sizeof(*this); 00238 } 00239 00240 }} 00241 00242 #endif 00243 00244 // STATISTICS: kernel-prop