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 * Gabor Szokoli <szokoli@gecode.org> 7 * 8 * Copyright: 9 * Guido Tack, 2004 10 * Christian Schulte, 2004 11 * Gabor Szokoli, 2004 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 38 39 40#include <gecode/set.hh> 41#include <gecode/int.hh> 42#include <gecode/set/rel.hh> 43 44namespace Gecode { namespace Set { namespace Channel { 45 46 template<class View> 47 forceinline 48 ChannelSorted<View>::ChannelSorted(Home home, View y0, 49 ViewArray< Gecode::Int::IntView >& ys) 50 : Propagator(home), x0(y0), xs(ys) { 51 x0.subscribe(home,*this, PC_SET_ANY); 52 xs.subscribe(home,*this, Gecode::Int::PC_INT_BND); 53 } 54 55 template<class View> 56 forceinline 57 ChannelSorted<View>::ChannelSorted(Space& home, ChannelSorted& p) 58 : Propagator(home,p) { 59 x0.update(home,p.x0); 60 xs.update(home,p.xs); 61 } 62 63 template<class View> 64 forceinline ExecStatus 65 ChannelSorted<View>::post(Home home, View x0, 66 ViewArray<Gecode::Int::IntView>& xs) { 67 unsigned int xs_size = static_cast<unsigned int>(xs.size()); 68 GECODE_ME_CHECK(x0.cardMin(home,xs_size)); 69 GECODE_ME_CHECK(x0.cardMax(home,xs_size)); 70 if (xs_size == 1) { 71 SingletonView sv(xs[0]); 72 GECODE_ES_CHECK((Rel::Eq<View, 73 SingletonView>::post(home,x0, sv))); 74 } else { 75 // Sharing in xs is handled correctly in the propagator: 76 // if two views in xs are shared, this leads to failure. 77 (void) new (home) ChannelSorted(home,x0,xs); 78 } 79 return ES_OK; 80 } 81 82 template<class View> 83 PropCost 84 ChannelSorted<View>::cost(const Space&, const ModEventDelta&) const { 85 return PropCost::linear(PropCost::LO, xs.size()+1); 86 } 87 88 template<class View> 89 void 90 ChannelSorted<View>::reschedule(Space& home) { 91 x0.reschedule(home,*this, PC_SET_ANY); 92 xs.reschedule(home,*this, Gecode::Int::PC_INT_BND); 93 } 94 95 template<class View> 96 forceinline size_t 97 ChannelSorted<View>::dispose(Space& home) { 98 x0.cancel(home,*this, PC_SET_ANY); 99 xs.cancel(home,*this, Gecode::Int::PC_INT_BND); 100 (void) Propagator::dispose(home); 101 return sizeof(*this); 102 } 103 104 template<class View> 105 Actor* 106 ChannelSorted<View>::copy(Space& home) { 107 return new (home) ChannelSorted(home,*this); 108 } 109 110 template<class View> 111 ExecStatus 112 ChannelSorted<View>::propagate(Space& home, const ModEventDelta&) { 113 114 int xs_size = xs.size(); 115 116 bool loopFlag; 117 118 do { 119 loopFlag = false; 120 121 // Order int vars in xs 122 GECODE_ME_CHECK(xs[0].gq(home,x0.lubMin())); 123 for (int i=xs_size-1; i--; ) { 124 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i+1].gq(home,xs[i].min() + 1)); 125 } 126 127 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[xs_size-1].lq(home,x0.lubMax())); 128 for (int i=xs_size-2; i--; ) { 129 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].lq(home,xs[i+1].max() - 1)); 130 } 131 132 // if y from xs is assigned, add to glb(x0) 133 for (int i=xs_size; i--; ) { 134 if (xs[i].assigned()) { 135 GECODE_ME_CHECK_MODIFIED(loopFlag, x0.include(home,xs[i].val())); 136 } 137 } 138 139 // intersect every y in xs with lub(x0) 140 for (int i=xs_size; i--; ) { 141 LubRanges<View> ub(x0); 142 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].inter_r(home,ub,false)); 143 } 144 145 // remove gaps between vars in xs from lub(x0) 146 GECODE_ME_CHECK_MODIFIED(loopFlag, 147 x0.exclude(home,Limits::min,xs[0].min()-1)); 148 GECODE_ME_CHECK_MODIFIED(loopFlag, 149 x0.exclude(home,xs[xs_size-1].max()+1, 150 Limits::max)); 151 152 for (int i=xs_size-1; i--; ) { 153 int start = xs[i].max() + 1; 154 int end = xs[i+1].min() - 1; 155 if (start<=end) { 156 GECODE_ME_CHECK_MODIFIED(loopFlag, x0.exclude(home,start,end)); 157 } 158 } 159 160 // try to assign vars in xs from glb(x0) 161 if (x0.glbSize()>0) { 162 163 LubRanges<View> ub(x0); 164 Iter::Ranges::ToValues<LubRanges<View> > ubv(ub); 165 GlbRanges<View> lb(x0); 166 Iter::Ranges::ToValues<GlbRanges<View> > lbv(lb); 167 168 int i=0; 169 for (; ubv() && lbv() && ubv.val()==lbv.val(); 170 ++ubv, ++lbv, i++) { 171 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].eq(home,lbv.val())); 172 } 173 174 if (i<xs_size-1 && x0.lubMax()==x0.glbMax()) { 175 LubRanges<View> lbx0(x0); 176 GlbRanges<View> ubx0(x0); 177 Iter::Ranges::Inter<LubRanges<View>,GlbRanges<View> > 178 inter(lbx0, ubx0); 179 180 int to = x0.glbMax(); 181 int from = to; 182 while (inter()) { 183 from = inter.min(); 184 ++inter; 185 } 186 187 int k=xs_size-1; 188 for (int j=to; j>=from;j--,k--) { 189 GECODE_ME_CHECK_MODIFIED(loopFlag, xs[k].eq(home,j)); 190 } 191 } 192 } 193 194 } while (loopFlag); 195 196 for (int i=xs_size; i--; ) 197 if (!xs[i].assigned()) 198 return ES_FIX; 199 return home.ES_SUBSUMED(*this); 200 } 201 202}}} 203 204// STATISTICS: set-prop