Generated on Fri Aug 24 2012 04:52:21 for Gecode by doxygen 1.8.1.1
channel-bool.hpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Copyright:
7  * Guido Tack, 2004
8  *
9  * Last modified:
10  * $Date: 2010-03-10 21:36:44 +1100 (Wed, 10 Mar 2010) $ by $Author: schulte $
11  * $Revision: 10387 $
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 #include <gecode/int.hh>
39 
40 namespace Gecode { namespace Set { namespace Int {
41 
42  template<class View>
43  template<class A>
47  Council<A>& c, int index)
48  : Advisor(home,p,c), idx(index) {
49  if (idx == -1)
50  p.y.subscribe(home,*this);
51  else {
52  p.x[idx].subscribe(home,*this);
53  }
54  }
55 
56  template<class View>
59  IndexAdvisor& a)
60  : Advisor(home,share,a), idx(a.idx) {}
61 
62  template<class View>
63  forceinline int
65  return idx;
66  }
67 
68  template<class View>
69  template<class A>
70  forceinline void
72  ChannelBool<View>& p = static_cast<ChannelBool<View>&>(propagator());
73  if (idx == -1)
74  p.y.cancel(home,*this);
75  else {
76  p.x[idx].cancel(home,*this);
77  }
78  Advisor::dispose(home,c);
79  }
80 
81  template<class View>
85  View y0)
86  : Super(home,x0,y0), co(home), running(false) {
87  bool assigned = false;
88  for (int i=x.size(); i--;) {
89  if (x[i].zero()) {
90  assigned = true;
91  SetDelta d;
92  zeros.include(home, i, i, d);
93  } else if (x[i].one()) {
94  assigned = true;
95  SetDelta d;
96  ones.include(home, i, i, d);
97  } else {
98  (void) new (home) IndexAdvisor(home,*this,co,i);
99  }
100  }
101  if (assigned)
103  View::schedule(home, *this, y.assigned() ? ME_SET_VAL : ME_SET_BB);
104  (void) new (home) IndexAdvisor(home,*this,co,-1);
105  }
106 
107  template<class View>
110  : Super(home,share,p), running(false) {
111  co.update(home, share, p.co);
112  }
113 
114  template<class View>
117  View y) {
118  GECODE_ME_CHECK(y.intersect(home, 0, x.size()-1));
119  (void) new (home) ChannelBool(home,x,y);
120  return ES_OK;
121  }
122 
123  template<class View>
124  PropCost
126  return PropCost::quadratic(PropCost::LO, x.size()+1);
127  }
128 
129  template<class View>
130  forceinline size_t
132  co.dispose(home);
133  (void) Super::dispose(home);
134  return sizeof(*this);
135  }
136 
137  template<class View>
138  Actor*
139  ChannelBool<View>::copy(Space& home, bool share) {
140  return new (home) ChannelBool(home,share,*this);
141  }
142 
143  template<class View>
144  ExecStatus
146  running = true;
147  if (zeros.size() > 0) {
148  BndSetRanges zi(zeros);
149  GECODE_ME_CHECK(y.excludeI(home, zi));
150  zeros.init(home);
151  }
152  if (ones.size() > 0) {
153  BndSetRanges oi(ones);
154  GECODE_ME_CHECK(y.includeI(home, oi));
155  ones.init(home);
156  }
157  running = false;
158 
159  if (delta.glbMin() != 1 || delta.glbMax() != 0) {
160  if (!delta.glbAny()) {
161  for (int i=delta.glbMin(); i<=delta.glbMax(); i++)
162  GECODE_ME_CHECK(x[i].one(home));
163  } else {
164  GlbRanges<View> glb(y);
165  for (Iter::Ranges::ToValues<GlbRanges<View> > gv(glb); gv(); ++gv) {
166  GECODE_ME_CHECK(x[gv.val()].one(home));
167  }
168  }
169  }
170  if (delta.lubMin() != 1 || delta.lubMax() != 0) {
171  if (!delta.lubAny()) {
172  for (int i=delta.lubMin(); i<=delta.lubMax(); i++)
173  GECODE_ME_CHECK(x[i].zero(home));
174  } else {
175  int cur = 0;
176  for (LubRanges<View> lub(y); lub(); ++lub) {
177  for (; cur < lub.min(); cur++) {
178  GECODE_ME_CHECK(x[cur].zero(home));
179  }
180  cur = lub.max() + 1;
181  }
182  for (; cur < x.size(); cur++) {
183  GECODE_ME_CHECK(x[cur].zero(home));
184  }
185  }
186  }
187 
188  new (&delta) SetDelta();
189 
190  return y.assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
191  }
192 
193  template<class View>
194  ExecStatus
196  IndexAdvisor& a = static_cast<IndexAdvisor&>(_a);
197  const SetDelta& d = static_cast<const SetDelta&>(_d);
198 
199  ModEvent me = View::modevent(d);
200  int index = a.index();
201  if ( (running && index == -1 && me != ME_SET_VAL)
202  || (index == -1 && me == ME_SET_CARD) ) {
203  return ES_OK;
204  }
205 
206  if (index >= 0) {
207  if (x[index].zero()) {
208  SetDelta dummy;
209  zeros.include(home, index, index, dummy);
210  } else {
211  assert(x[index].one());
212  SetDelta dummy;
213  ones.include(home, index, index, dummy);
214  }
215  return home.ES_NOFIX_DISPOSE( co, a);
216  }
217 
218  if ((a.index() == -1) && Rel::testSetEventLB(me)) {
219  if (d.glbAny()) {
220  new (&delta)
221  SetDelta(2,0, delta.lubMin(), delta.lubMax());
222  } else {
223  if (delta.glbMin() == 1 && delta.glbMax() == 0) {
224  new (&delta)
225  SetDelta(d.glbMin(), d.glbMax(),
226  delta.lubMin(), delta.lubMax());
227  } else {
228  if (delta.glbMin() != 2 || delta.glbMax() != 0) {
229  if ((delta.glbMin() <= d.glbMin() && delta.glbMax() >= d.glbMin())
230  ||
231  (delta.glbMin() <= d.glbMax() && delta.glbMax() >= d.glbMax())
232  ) {
233  new (&delta)
234  SetDelta(std::min(delta.glbMin(), d.glbMin()),
235  std::max(delta.glbMax(), d.glbMax()),
236  delta.lubMin(), delta.lubMax());
237  } else {
238  new (&delta)
239  SetDelta(2, 0, delta.lubMin(), delta.lubMax());
240  }
241  }
242  }
243  }
244  }
245  if ((a.index() == -1) && Rel::testSetEventUB(me)) {
246  if (d.lubAny()) {
247  new (&delta)
248  SetDelta(delta.glbMin(), delta.glbMax(), 2,0);
249  } else {
250  if (delta.lubMin() == 1 && delta.lubMax() == 0) {
251  new (&delta)
252  SetDelta(delta.glbMin(), delta.glbMax(),
253  d.lubMin(), d.lubMax());
254  } else {
255  if (delta.lubMin() != 2 || delta.lubMax() != 0) {
256  if ((delta.lubMin() <= d.lubMin() && delta.lubMax() >= d.lubMin())
257  ||
258  (delta.lubMin() <= d.lubMax() && delta.lubMax() >= d.lubMax())
259  ) {
260  new (&delta)
261  SetDelta(delta.lubMin(), delta.lubMax(),
262  std::min(delta.lubMin(), d.lubMin()),
263  std::max(delta.lubMax(), d.lubMax())
264  );
265  } else {
266  new (&delta)
267  SetDelta(delta.glbMin(), delta.glbMax(), 2, 0);
268  }
269  }
270  }
271  }
272  }
273 
274  if (y.assigned())
275  return home.ES_NOFIX_DISPOSE( co, a);
276  else
277  return ES_NOFIX;
278  }
279 
280 }}}
281 
282 // STATISTICS: set-prop