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 * Gabor Szokoli <szokoli@gecode.org> 6 * Vincent Barichard <Vincent.Barichard@univ-angers.fr> 7 * 8 * Copyright: 9 * Christian Schulte, 2003 10 * Gabor Szokoli, 2003 11 * Vincent Barichard, 2012 12 * 13 * This file is part of Gecode, the generic constraint 14 * development environment: 15 * http://www.gecode.org 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining 18 * a copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, including 20 * without limitation the rights to use, copy, modify, merge, publish, 21 * distribute, sublicense, and/or sell copies of the Software, and to 22 * permit persons to whom the Software is furnished to do so, subject to 23 * the following conditions: 24 * 25 * The above copyright notice and this permission notice shall be 26 * included in all copies or substantial portions of the Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 * 36 */ 37 38namespace Gecode { namespace Float { namespace Rel { 39 40 /* 41 * Less or equal propagator 42 * 43 */ 44 45 template<class View> 46 forceinline 47 Lq<View>::Lq(Home home, View x0, View x1) 48 : BinaryPropagator<View,PC_FLOAT_BND>(home,x0,x1) {} 49 50 template<class View> 51 ExecStatus 52 Lq<View>::post(Home home, View x0, View x1) { 53 GECODE_ME_CHECK(x0.lq(home,x1.max())); 54 GECODE_ME_CHECK(x1.gq(home,x0.min())); 55 if ((x0 != x1) && (x0.max() > x1.min())) 56 (void) new (home) Lq<View>(home,x0,x1); 57 return ES_OK; 58 } 59 60 template<class View> 61 forceinline 62 Lq<View>::Lq(Space& home, Lq<View>& p) 63 : BinaryPropagator<View,PC_FLOAT_BND>(home,p) {} 64 65 template<class View> 66 Actor* 67 Lq<View>::copy(Space& home) { 68 return new (home) Lq<View>(home,*this); 69 } 70 71 template<class View> 72 ExecStatus 73 Lq<View>::propagate(Space& home, const ModEventDelta&) { 74 GECODE_ME_CHECK(x0.lq(home,x1.max())); 75 GECODE_ME_CHECK(x1.gq(home,x0.min())); 76 return (x0.assigned() || x1.assigned() || (x0.max() <= x1.min())) ? home.ES_SUBSUMED(*this) : ES_FIX; 77 } 78 79 80 /* 81 * Less propagator 82 * 83 */ 84 template<class View> 85 forceinline 86 Le<View>::Le(Home home, View x0, View x1) 87 : BinaryPropagator<View,PC_FLOAT_BND>(home,x0,x1) {} 88 89 template<class View> 90 ExecStatus 91 Le<View>::post(Home home, View x0, View x1) { 92 GECODE_ME_CHECK(x0.lq(home,x1.max())); 93 GECODE_ME_CHECK(x1.gq(home,x0.min())); 94 if (x0.assigned() && x1.assigned()) { 95 if (x0.max() >= x1.min()) 96 return ES_FAILED; 97 } else if (x0 == x1) 98 return ES_FAILED; 99 if (x0.max() >= x1.min()) 100 (void) new (home) Le<View>(home,x0,x1); 101 return ES_OK; 102 } 103 104 template<class View> 105 forceinline 106 Le<View>::Le(Space& home, Le<View>& p) 107 : BinaryPropagator<View,PC_FLOAT_BND>(home,p) {} 108 109 template<class View> 110 Actor* 111 Le<View>::copy(Space& home) { 112 return new (home) Le<View>(home,*this); 113 } 114 115 template<class View> 116 ExecStatus 117 Le<View>::propagate(Space& home, const ModEventDelta&) { 118 GECODE_ME_CHECK(x0.lq(home,x1.max())); 119 GECODE_ME_CHECK(x1.gq(home,x0.min())); 120 if (x0.assigned() && x1.assigned()) { 121 return (x0.max() >= x1.min()) ? ES_FAILED : home.ES_SUBSUMED(*this); 122 } 123 return (x0.max() < x1.min()) ? home.ES_SUBSUMED(*this) : ES_FIX; 124 } 125 126 127 128 129 /* 130 * Reified less or equal propagator 131 * 132 */ 133 134 template<class View, class CtrlView, ReifyMode rm> 135 forceinline 136 ReLq<View,CtrlView,rm>::ReLq(Home home, View x0, View x1, CtrlView b) 137 : Int::ReBinaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,x0,x1,b) {} 138 139 template<class View, class CtrlView, ReifyMode rm> 140 ExecStatus 141 ReLq<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b) { 142 if (b.one()) { 143 if (rm == RM_PMI) 144 return ES_OK; 145 return Lq<View>::post(home,x0,x1); 146 } 147 if (b.zero()) { 148 if (rm == RM_IMP) 149 return ES_OK; 150 return Le<View>::post(home,x1,x0); 151 } 152 if (x0 != x1) { 153 switch (rtest_lq(x0,x1)) { 154 case RT_TRUE: 155 if (rm != RM_IMP) 156 GECODE_ME_CHECK(b.one_none(home)); 157 break; 158 case RT_FALSE: 159 if (rm != RM_PMI) 160 GECODE_ME_CHECK(b.zero_none(home)); 161 break; 162 case RT_MAYBE: 163 if (!x0.assigned() || !x1.assigned()) 164 (void) new (home) ReLq<View,CtrlView,rm>(home,x0,x1,b); 165 else { 166 if (rm != RM_IMP) 167 GECODE_ME_CHECK(b.one_none(home)); 168 } 169 break; 170 default: GECODE_NEVER; 171 } 172 } else if (rm != RM_IMP) { 173 GECODE_ME_CHECK(b.one_none(home)); 174 } 175 return ES_OK; 176 } 177 178 template<class View, class CtrlView, ReifyMode rm> 179 forceinline 180 ReLq<View,CtrlView,rm>::ReLq(Space& home, ReLq& p) 181 : Int::ReBinaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,p) {} 182 183 template<class View, class CtrlView, ReifyMode rm> 184 Actor* 185 ReLq<View,CtrlView,rm>::copy(Space& home) { 186 return new (home) ReLq<View,CtrlView,rm>(home,*this); 187 } 188 189 template<class View, class CtrlView, ReifyMode rm> 190 ExecStatus 191 ReLq<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) { 192 if (b.one()) { 193 if (rm != RM_PMI) 194 GECODE_REWRITE(*this,Lq<View>::post(home(*this),x0,x1)); 195 } else if (b.zero()) { 196 if (rm != RM_IMP) 197 GECODE_REWRITE(*this,Le<View>::post(home(*this),x1,x0)); 198 } else { 199 switch (rtest_lq(x0,x1)) { 200 case RT_TRUE: 201 if (rm != RM_IMP) 202 GECODE_ME_CHECK(b.one_none(home)); 203 break; 204 case RT_FALSE: 205 if (rm != RM_PMI) 206 GECODE_ME_CHECK(b.zero_none(home)); 207 break; 208 case RT_MAYBE: 209 if (!x0.assigned() || !x1.assigned()) 210 return ES_FIX; 211 else { 212 if (rm != RM_IMP) 213 GECODE_ME_CHECK(b.one_none(home)); 214 break; 215 } 216 default: GECODE_NEVER; 217 } 218 } 219 return home.ES_SUBSUMED(*this); 220 } 221 222 /* 223 * Reified less or equal propagator involving one variable 224 * 225 */ 226 227 template<class View, class CtrlView, ReifyMode rm> 228 forceinline 229 ReLqFloat<View,CtrlView,rm>::ReLqFloat(Home home, View x, FloatVal c0, CtrlView b) 230 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,x,b), c(c0) {} 231 232 template<class View, class CtrlView, ReifyMode rm> 233 ExecStatus 234 ReLqFloat<View,CtrlView,rm>::post(Home home, View x, FloatVal c, CtrlView b) { 235 if (b.one()) { 236 if (rm != RM_PMI) 237 GECODE_ME_CHECK(x.lq(home,c.max())); 238 } if (b.zero()) { 239 if (rm != RM_IMP) { 240 GECODE_ME_CHECK(x.gq(home,c.min())); 241 if (x.assigned() && (x.min() <= c.max())) 242 return ES_FAILED; 243 (void) new (home) ReLqFloat<View,CtrlView,rm>(home,x,c,b); 244 } 245 } else { 246 switch (rtest_lq(x,c)) { 247 case RT_TRUE: 248 if (rm != RM_IMP) 249 GECODE_ME_CHECK(b.one(home)); 250 break; 251 case RT_FALSE: 252 if (rm != RM_PMI) 253 GECODE_ME_CHECK(b.zero(home)); 254 break; 255 case RT_MAYBE: 256 (void) new (home) ReLqFloat<View,CtrlView,rm>(home,x,c,b); 257 break; 258 default: GECODE_NEVER; 259 } 260 } 261 return ES_OK; 262 } 263 264 265 template<class View, class CtrlView, ReifyMode rm> 266 forceinline 267 ReLqFloat<View,CtrlView,rm>::ReLqFloat(Space& home, ReLqFloat& p) 268 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,p), c(p.c) {} 269 270 template<class View, class CtrlView, ReifyMode rm> 271 Actor* 272 ReLqFloat<View,CtrlView,rm>::copy(Space& home) { 273 return new (home) ReLqFloat<View,CtrlView,rm>(home,*this); 274 } 275 276 template<class View, class CtrlView, ReifyMode rm> 277 ExecStatus 278 ReLqFloat<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) { 279 if (b.one()) { 280 if (rm != RM_PMI) 281 GECODE_ME_CHECK(x0.lq(home,c.max())); 282 } else if (b.zero()) { 283 if (rm != RM_IMP) 284 { 285 GECODE_ME_CHECK(x0.gq(home,c.min())); 286 if (x0.assigned()) { 287 return (x0.min() <= c.max()) ? ES_FAILED : home.ES_SUBSUMED(*this); 288 } 289 } 290 } else { 291 switch (rtest_lq(x0,c)) { 292 case RT_TRUE: 293 if (rm != RM_IMP) 294 GECODE_ME_CHECK(b.one(home)); 295 break; 296 case RT_FALSE: 297 if (rm != RM_PMI) 298 GECODE_ME_CHECK(b.zero(home)); 299 break; 300 case RT_MAYBE: 301 return ES_FIX; 302 default: GECODE_NEVER; 303 } 304 } 305 return home.ES_SUBSUMED(*this); 306 } 307 308 309 /* 310 * Reified less 311 * 312 */ 313 314 template<class View, class CtrlView, ReifyMode rm> 315 forceinline 316 ReLeFloat<View,CtrlView,rm>::ReLeFloat(Home home, View x, FloatVal c0, CtrlView b) 317 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,x,b), c(c0) {} 318 319 template<class View, class CtrlView, ReifyMode rm> 320 ExecStatus 321 ReLeFloat<View,CtrlView,rm>::post(Home home, View x, FloatVal c, CtrlView b) { 322 if (b.one()) { 323 if (rm != RM_PMI) 324 { 325 GECODE_ME_CHECK(x.lq(home,c.max())); 326 if (x.assigned() && (x.max() >= c.min())) 327 return ES_FAILED; 328 (void) new (home) ReLeFloat<View,CtrlView,rm>(home,x,c,b); 329 } 330 } else if (b.zero()) { 331 if (rm != RM_IMP) 332 GECODE_ME_CHECK(x.gq(home,c.min())); 333 } else { 334 switch (rtest_le(x,c)) { 335 case RT_TRUE: 336 if (rm != RM_IMP) 337 GECODE_ME_CHECK(b.one(home)); 338 break; 339 case RT_FALSE: 340 if (rm != RM_PMI) 341 GECODE_ME_CHECK(b.zero(home)); 342 break; 343 case RT_MAYBE: 344 (void) new (home) ReLeFloat<View,CtrlView,rm>(home,x,c,b); 345 break; 346 default: GECODE_NEVER; 347 } 348 } 349 return ES_OK; 350 } 351 352 353 template<class View, class CtrlView, ReifyMode rm> 354 forceinline 355 ReLeFloat<View,CtrlView,rm>::ReLeFloat(Space& home, ReLeFloat& p) 356 : Int::ReUnaryPropagator<View,PC_FLOAT_BND,CtrlView>(home,p), c(p.c) {} 357 358 template<class View, class CtrlView, ReifyMode rm> 359 Actor* 360 ReLeFloat<View,CtrlView,rm>::copy(Space& home) { 361 return new (home) ReLeFloat<View,CtrlView,rm>(home,*this); 362 } 363 364 template<class View, class CtrlView, ReifyMode rm> 365 ExecStatus 366 ReLeFloat<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) { 367 if (b.one()) { 368 if (rm != RM_PMI) 369 { 370 GECODE_ME_CHECK(x0.lq(home,c.max())); 371 if (x0.assigned()) { 372 return (x0.max() >= c.min()) ? ES_FAILED : home.ES_SUBSUMED(*this); 373 } 374 } 375 } else if (b.zero()) { 376 if (rm != RM_IMP) 377 GECODE_ME_CHECK(x0.gq(home,c.min())); 378 } else { 379 switch (rtest_le(x0,c)) { 380 case RT_TRUE: 381 if (rm != RM_IMP) 382 GECODE_ME_CHECK(b.one(home)); 383 break; 384 case RT_FALSE: 385 if (rm != RM_PMI) 386 GECODE_ME_CHECK(b.zero(home)); 387 break; 388 case RT_MAYBE: 389 return ES_FIX; 390 default: GECODE_NEVER; 391 } 392 } 393 return home.ES_SUBSUMED(*this); 394 } 395 396}}} 397 398// STATISTICS: float-prop 399