this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * Christian Schulte <schulte@gecode.org> 6 * 7 * Bugfixes provided by: 8 * Grégoire Dooms <dooms@info.ucl.ac.be> 9 * 10 * Copyright: 11 * Guido Tack, 2004 12 * Christian Schulte, 2004 13 * 14 * This file is part of Gecode, the generic constraint 15 * development environment: 16 * http://www.gecode.org 17 * 18 * Permission is hereby granted, free of charge, to any person obtaining 19 * a copy of this software and associated documentation files (the 20 * "Software"), to deal in the Software without restriction, including 21 * without limitation the rights to use, copy, modify, merge, publish, 22 * distribute, sublicense, and/or sell copies of the Software, and to 23 * permit persons to whom the Software is furnished to do so, subject to 24 * the following conditions: 25 * 26 * The above copyright notice and this permission notice shall be 27 * included in all copies or substantial portions of the Software. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 32 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 33 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 34 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 35 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 * 37 */ 38 39namespace Gecode { namespace Set { namespace Rel { 40 41 template<class View0, class View1, class CtrlView, ReifyMode rm> 42 forceinline 43 ReEq<View0,View1,CtrlView,rm>::ReEq(Home home, View0 y0, View1 y1, 44 CtrlView y2) 45 : Propagator(home), x0(y0), x1(y1), b(y2) { 46 b.subscribe(home,*this, Gecode::Int::PC_INT_VAL); 47 x0.subscribe(home,*this, PC_SET_ANY); 48 x1.subscribe(home,*this, PC_SET_ANY); 49 } 50 51 template<class View0, class View1, class CtrlView, ReifyMode rm> 52 forceinline 53 ReEq<View0,View1,CtrlView,rm>::ReEq(Space& home, ReEq& p) 54 : Propagator(home,p) { 55 x0.update(home,p.x0); 56 x1.update(home,p.x1); 57 b.update(home,p.b); 58 } 59 60 template<class View0, class View1, class CtrlView, ReifyMode rm> 61 PropCost 62 ReEq<View0,View1,CtrlView,rm>::cost(const Space&, const ModEventDelta&) const { 63 return PropCost::ternary(PropCost::LO); 64 } 65 66 template<class View0, class View1, class CtrlView, ReifyMode rm> 67 void 68 ReEq<View0,View1,CtrlView,rm>::reschedule(Space& home) { 69 b.reschedule(home,*this, Gecode::Int::PC_INT_VAL); 70 x0.reschedule(home,*this, PC_SET_ANY); 71 x1.reschedule(home,*this, PC_SET_ANY); 72 } 73 74 template<class View0, class View1, class CtrlView, ReifyMode rm> 75 forceinline size_t 76 ReEq<View0,View1,CtrlView,rm>::dispose(Space& home) { 77 b.cancel(home,*this, Gecode::Int::PC_INT_VAL); 78 x0.cancel(home,*this, PC_SET_ANY); 79 x1.cancel(home,*this, PC_SET_ANY); 80 (void) Propagator::dispose(home); 81 return sizeof(*this); 82 } 83 84 template<class View0, class View1, class CtrlView, ReifyMode rm> 85 ExecStatus 86 ReEq<View0,View1,CtrlView,rm>::post(Home home, View0 x0, View1 x1, 87 CtrlView b) { 88 if (!same(x0,x1)) { 89 (void) new (home) ReEq<View0,View1,CtrlView,rm>(home,x0,x1,b); 90 } else if (rm != RM_IMP) { 91 GECODE_ME_CHECK(b.one(home)); 92 } 93 return ES_OK; 94 } 95 96 template<class View0, class View1, class CtrlView, ReifyMode rm> 97 Actor* 98 ReEq<View0,View1,CtrlView,rm>::copy(Space& home) { 99 return new (home) ReEq<View0,View1,CtrlView,rm>(home,*this); 100 } 101 102 template<class View0, class View1, class CtrlView, ReifyMode rm> 103 ExecStatus 104 ReEq<View0,View1,CtrlView,rm>::propagate(Space& home, 105 const ModEventDelta&) { 106 if (b.one()) { 107 if (rm == RM_PMI) 108 return home.ES_SUBSUMED(*this); 109 GECODE_REWRITE(*this,(Eq<View0,View1>::post(home(*this),x0,x1))); 110 } 111 if (b.zero()) { 112 if (rm == RM_IMP) 113 return home.ES_SUBSUMED(*this); 114 GECODE_REWRITE(*this,(Distinct<View0,View1>::post(home(*this),x0,x1))); 115 } 116 117 if (x0.assigned() && x1.assigned()) { 118 // directly test x0==x1 119 GlbRanges<View0> x0lb(x0); 120 GlbRanges<View1> x1lb(x1); 121 bool x0eqx1 = true; 122 for (; x0lb() && x1lb(); ++x0lb, ++x1lb) { 123 if (x0lb.min() != x1lb.min() || 124 x0lb.max() != x1lb.max()) { 125 x0eqx1 = false; 126 break; 127 } 128 } 129 if (x0eqx1 && !x0lb() && !x1lb()) { 130 if (rm != RM_IMP) 131 GECODE_ME_CHECK(b.one_none(home)); 132 return home.ES_SUBSUMED(*this); 133 } else { 134 if (rm != RM_PMI) 135 GECODE_ME_CHECK(b.zero_none(home)); 136 return home.ES_SUBSUMED(*this); 137 } 138 } 139 140 // check whether cardinalities still allow equality 141 if (x0.cardMin() > x1.cardMax() || 142 x1.cardMin() > x0.cardMax()) { 143 if (rm != RM_PMI) 144 GECODE_ME_CHECK(b.zero_none(home)); 145 return home.ES_SUBSUMED(*this); 146 } 147 148 // check glb(x0) subset lub(x1) 149 GlbRanges<View0> x0lb(x0); 150 LubRanges<View1> x1ub(x1); 151 Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub); 152 if ( diff1() ) { 153 if (rm != RM_PMI) 154 GECODE_ME_CHECK(b.zero_none(home)); 155 return home.ES_SUBSUMED(*this); 156 } 157 158 // check glb(x1) subset lub(x0) 159 GlbRanges<View1> x1lb(x1); 160 LubRanges<View0> x0ub(x0); 161 Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View0> > diff2(x1lb, x0ub); 162 if ( diff2() ) { 163 if (rm != RM_PMI) 164 GECODE_ME_CHECK(b.zero_none(home)); 165 return home.ES_SUBSUMED(*this); 166 } 167 168 return ES_FIX; 169 } 170 171}}} 172 173// STATISTICS: set-prop