this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2013 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include <gecode/int/rel.hh> 35 36#include <algorithm> 37 38namespace Gecode { namespace Int { namespace Bool { 39 40 template<class V0, class V1, class V2, PropCond pc> 41 forceinline 42 IteBase<V0,V1,V2,pc>::IteBase(Home home, BoolView b0, V0 y0, V1 y1, V2 y2) 43 : Propagator(home), b(b0), x0(y0), x1(y1), x2(y2) { 44 b.subscribe(home,*this,PC_BOOL_VAL); 45 x0.subscribe(home,*this,pc); 46 x1.subscribe(home,*this,pc); 47 x2.subscribe(home,*this,pc); 48 } 49 50 template<class V0, class V1, class V2, PropCond pc> 51 forceinline 52 IteBase<V0,V1,V2,pc>::IteBase(Space& home, IteBase<V0,V1,V2,pc>& p) 53 : Propagator(home,p) { 54 b.update(home,p.b); 55 x0.update(home,p.x0); 56 x1.update(home,p.x1); 57 x2.update(home,p.x2); 58 } 59 60 template<class V0, class V1, class V2, PropCond pc> 61 PropCost 62 IteBase<V0,V1,V2,pc>::cost(const Space&, const ModEventDelta&) const { 63 return PropCost::ternary(PropCost::LO); 64 } 65 66 template<class V0, class V1, class V2, PropCond pc> 67 void 68 IteBase<V0,V1,V2,pc>::reschedule(Space& home) { 69 b.reschedule(home,*this,PC_BOOL_VAL); 70 x0.reschedule(home,*this,pc); 71 x1.reschedule(home,*this,pc); 72 x2.reschedule(home,*this,pc); 73 } 74 75 template<class V0, class V1, class V2, PropCond pc> 76 forceinline size_t 77 IteBase<V0,V1,V2,pc>::dispose(Space& home) { 78 b.cancel(home,*this,PC_BOOL_VAL); 79 x0.cancel(home,*this,pc); 80 x1.cancel(home,*this,pc); 81 x2.cancel(home,*this,pc); 82 (void) Propagator::dispose(home); 83 return sizeof(*this); 84 } 85 86 87 88 template<class V0, class V1, class V2> 89 forceinline 90 IteBnd<V0,V1,V2>::IteBnd(Home home, BoolView b, V0 x0, V1 x1, V2 x2) 91 : IteBase<V0,V1,V2,PC_INT_BND>(home,b,x0,x1,x2) {} 92 93 template<class V0, class V1, class V2> 94 forceinline 95 IteBnd<V0,V1,V2>::IteBnd(Space& home, IteBnd<V0,V1,V2>& p) 96 : IteBase<V0,V1,V2,PC_INT_BND>(home,p) {} 97 98 template<class V0, class V1, class V2> 99 Actor* 100 IteBnd<V0,V1,V2>::copy(Space& home) { 101 return new (home) IteBnd<V0,V1,V2>(home,*this); 102 } 103 104 template<class V0, class V1, class V2> 105 inline ExecStatus 106 IteBnd<V0,V1,V2>::post(Home home, BoolView b, V0 x0, V1 x1, V2 x2) { 107 if (b.one()) 108 return Rel::EqBnd<V2,V0>::post(home,x2,x0); 109 if (b.zero()) 110 return Rel::EqBnd<V2,V1>::post(home,x2,x1); 111 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max()))); 112 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min()))); 113 (void) new (home) IteBnd<V0,V1,V2>(home,b,x0,x1,x2); 114 return ES_OK; 115 } 116 117 template<class V0, class V1, class V2> 118 ExecStatus 119 IteBnd<V0,V1,V2>::propagate(Space& home, const ModEventDelta&) { 120 if (b.one()) 121 GECODE_REWRITE(*this,(Rel::EqBnd<V2,V0>::post(home(*this),x2,x0))); 122 if (b.zero()) 123 GECODE_REWRITE(*this,(Rel::EqBnd<V2,V1>::post(home(*this),x2,x1))); 124 125 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max()))); 126 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min()))); 127 128 RelTest eq20 = rtest_eq_bnd(x2,x0); 129 RelTest eq21 = rtest_eq_bnd(x2,x1); 130 131 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE)) 132 return ES_FAILED; 133 134 if (eq20 == RT_FALSE) { 135 GECODE_ME_CHECK(b.zero_none(home)); 136 if (eq21 == RT_TRUE) 137 return home.ES_SUBSUMED(*this); 138 else 139 GECODE_REWRITE(*this,(Rel::EqBnd<V2,V1>::post(home(*this),x2,x1))); 140 } 141 142 if (eq21 == RT_FALSE) { 143 GECODE_ME_CHECK(b.one_none(home)); 144 if (eq20 == RT_TRUE) 145 return home.ES_SUBSUMED(*this); 146 else 147 GECODE_REWRITE(*this,(Rel::EqBnd<V2,V0>::post(home(*this),x2,x0))); 148 } 149 150 if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE)) 151 return home.ES_SUBSUMED(*this); 152 153 return ES_FIX; 154 } 155 156 157 158 template<class V0, class V1, class V2> 159 forceinline 160 IteDom<V0,V1,V2>::IteDom(Home home, BoolView b, V0 x0, V1 x1, V2 x2) 161 : IteBase<V0,V1,V2,PC_INT_DOM>(home,b,x0,x1,x2) {} 162 163 template<class V0, class V1, class V2> 164 forceinline 165 IteDom<V0,V1,V2>::IteDom(Space& home, IteDom<V0,V1,V2>& p) 166 : IteBase<V0,V1,V2,PC_INT_DOM>(home,p) {} 167 168 template<class V0, class V1, class V2> 169 Actor* 170 IteDom<V0,V1,V2>::copy(Space& home) { 171 return new (home) IteDom<V0,V1,V2>(home,*this); 172 } 173 174 template<class V0, class V1, class V2> 175 inline ExecStatus 176 IteDom<V0,V1,V2>::post(Home home, BoolView b, V0 x0, V1 x1, V2 x2) { 177 if (b.one()) 178 return Rel::EqDom<V2,V0>::post(home,x2,x0); 179 if (b.zero()) 180 return Rel::EqDom<V2,V1>::post(home,x2,x1); 181 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max()))); 182 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min()))); 183 (void) new (home) IteDom<V0,V1,V2>(home,b,x0,x1,x2); 184 return ES_OK; 185 } 186 187 template<class V0, class V1, class V2> 188 PropCost 189 IteDom<V0,V1,V2>::cost(const Space&, const ModEventDelta& med) const { 190 if (V0::me(med) == ME_INT_DOM) 191 return PropCost::ternary(PropCost::HI); 192 else 193 return PropCost::ternary(PropCost::LO); 194 } 195 196 template<class V0, class V1, class V2> 197 ExecStatus 198 IteDom<V0,V1,V2>::propagate(Space& home, const ModEventDelta& med) { 199 if (b.one()) 200 GECODE_REWRITE(*this,(Rel::EqDom<V2,V0>::post(home(*this),x2,x0))); 201 if (b.zero()) 202 GECODE_REWRITE(*this,(Rel::EqDom<V2,V1>::post(home(*this),x2,x1))); 203 204 GECODE_ME_CHECK(x2.lq(home,std::max(x0.max(),x1.max()))); 205 GECODE_ME_CHECK(x2.gq(home,std::min(x0.min(),x1.min()))); 206 207 if (V0::me(med) != ME_INT_DOM) { 208 RelTest eq20 = rtest_eq_bnd(x2,x0); 209 RelTest eq21 = rtest_eq_bnd(x2,x1); 210 211 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE)) 212 return ES_FAILED; 213 214 if (eq20 == RT_FALSE) { 215 GECODE_ME_CHECK(b.zero_none(home)); 216 if (eq21 == RT_TRUE) 217 return home.ES_SUBSUMED(*this); 218 else 219 GECODE_REWRITE(*this, 220 (Rel::EqDom<V2,V1>::post(home(*this),x2,x1))); 221 } 222 223 if (eq21 == RT_FALSE) { 224 GECODE_ME_CHECK(b.one_none(home)); 225 if (eq20 == RT_TRUE) 226 return home.ES_SUBSUMED(*this); 227 else 228 GECODE_REWRITE(*this, 229 (Rel::EqDom<V2,V0>::post(home(*this),x2,x0))); 230 } 231 232 if ((eq20 == RT_TRUE) && (eq21 == RT_TRUE)) 233 return home.ES_SUBSUMED(*this); 234 235 return home.ES_FIX_PARTIAL(*this,V0::med(ME_INT_DOM)); 236 } 237 238 RelTest eq20 = rtest_eq_dom(x2,x0); 239 RelTest eq21 = rtest_eq_dom(x2,x1); 240 241 if ((eq20 == RT_FALSE) && (eq21 == RT_FALSE)) 242 return ES_FAILED; 243 244 if (eq20 == RT_FALSE) { 245 GECODE_ME_CHECK(b.zero_none(home)); 246 if (eq21 == RT_TRUE) 247 return home.ES_SUBSUMED(*this); 248 else 249 GECODE_REWRITE(*this, 250 (Rel::EqDom<V2,V1>::post(home(*this),x2,x1))); 251 } 252 253 if (eq21 == RT_FALSE) { 254 GECODE_ME_CHECK(b.one_none(home)); 255 if (eq20 == RT_TRUE) 256 return home.ES_SUBSUMED(*this); 257 else 258 GECODE_REWRITE(*this, 259 (Rel::EqDom<V2,V0>::post(home(*this),x2,x0))); 260 } 261 262 assert((eq20 != RT_TRUE) || (eq21 != RT_TRUE)); 263 264 ViewRanges<V0> r0(x0); 265 ViewRanges<V1> r1(x1); 266 Iter::Ranges::Union<ViewRanges<V0>,ViewRanges<V1> > u(r0,r1); 267 268 if (!shared<V0,V2>(x0,x2) && !shared<V1,V2>(x1,x2)) 269 GECODE_ME_CHECK(x2.inter_r(home,u,false)); 270 else 271 GECODE_ME_CHECK(x2.inter_r(home,u,true)); 272 273 return ES_FIX; 274 } 275 276}}} 277 278// STATISTICS: int-prop