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