Generated on Sat Feb 7 2015 02:01:20 for Gecode by doxygen 1.8.9.1
lq.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, 2011
8  *
9  * Last modified:
10  * $Date: 2013-02-08 16:47:00 +0100 (Fri, 08 Feb 2013) $ by $Author: schulte $
11  * $Revision: 13278 $
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 namespace Gecode { namespace Set { namespace Rel {
39 
44  protected:
46  unsigned int xsize;
50  int* ub;
52  bool xlm;
54  bool xum;
56  bool ylm;
58  bool yum;
60  void set(int i, bool j) {
61  if (j)
62  b.set(i);
63  else
64  b.clear(i);
65  }
66 
68  class CSIter {
69  public:
73  unsigned int i;
75  int xoff;
77  int yoff;
79  void operator++ (void) {
80  i++;
81  while (i<cs->xsize && !cs->b.get(xoff+2*i+yoff))
82  i++;
83  }
85  CSIter(void) {}
87  CSIter(CharacteristicSets& cs0, int xoff0, int yoff0)
88  : cs(&cs0), i(static_cast<unsigned int>(-1)),
89  xoff(xoff0), yoff(yoff0) {
90  ++(*this);
91  }
93  bool operator() (void) const { return i<cs->xsize; }
95  int val(void) const { return cs->ub[i]; }
96  };
97 
98  public:
100  template<class View0, class View1>
101  CharacteristicSets(Region& re, View0 x, View1 y);
102 
104  bool xmin(int i) const { return b.get(2*i); }
106  bool xmax(int i) const { return b.get(2*i+1); }
108  bool ymin(int i) const { return b.get(2*xsize+2*i); }
110  bool ymax(int i) const { return b.get(2*xsize+2*i+1); }
111 
113  void xmin(int i, bool j) { set(2*i,j); }
115  void xmax(int i, bool j) { set(2*i+1,j); }
117  void ymin(int i, bool j) { set(2*xsize+2*i,j); }
119  void ymax(int i, bool j) { set(2*xsize+2*i+1,j); }
120 
122  ModEvent xlq(int i, bool j) {
123  if (!j) {
124  if (xmin(i)) return ME_SET_FAILED;
125  if (xmax(i)) {
126  xmax(i,false);
127  xum=true;
128  }
129  }
130  return ME_SET_NONE;
131  }
133  ModEvent xgq(int i, bool j) {
134  if (j) {
135  if (!xmax(i)) return ME_SET_FAILED;
136  if (!xmin(i)) {
137  xmin(i,true);
138  xlm=true;
139  }
140  }
141  return ME_SET_NONE;
142  }
144  ModEvent ylq(int i, bool j) {
145  if (!j) {
146  if (ymin(i)) return ME_SET_FAILED;
147  if (ymax(i)) {
148  ymax(i,false);
149  yum=true;
150  }
151  }
152  return ME_SET_NONE;
153  }
155  ModEvent ygq(int i, bool j) {
156  if (j) {
157  if (!ymax(i)) return ME_SET_FAILED;
158  if (!ymin(i)) {
159  ymin(i,true);
160  ylm=true;
161  }
162  }
163  return ME_SET_NONE;
164  }
165 
167  int size(void) const { return xsize; }
168 
170  template<class View0, class View1>
171  ExecStatus prune(Space& home, View0 x, View1 y) {
172  if (xlm) {
173  CSIter i(*this,0,0);
175  GECODE_ME_CHECK(x.includeI(home,ir));
176  }
177  if (xum) {
178  CSIter i(*this,0,1);
180  GECODE_ME_CHECK(x.intersectI(home,ir));
181  }
182  if (ylm) {
183  CSIter i(*this,2*xsize,0);
185  GECODE_ME_CHECK(y.includeI(home,ir));
186  }
187  if (yum) {
188  CSIter i(*this,2*xsize,1);
190  GECODE_ME_CHECK(y.intersectI(home,ir));
191  }
192  return ES_OK;
193  }
194 
195  };
196 
197  template<class View0, class View1>
199  : xlm(false), xum(false), ylm(false), yum(false) {
200  LubRanges<View0> xlub(x);
201  LubRanges<View1> ylub(y);
203  Iter::Ranges::Cache xylubc(re,xylub);
204  xsize = Iter::Ranges::size(xylubc);
205  b.init(re,4*xsize);
206  ub = re.alloc<int>(xsize);
207  xylubc.reset();
209  LubRanges<View0> xur(x);
210  GlbRanges<View0> xlr(x);
211  LubRanges<View1> yur(y);
212  GlbRanges<View1> ylr(y);
217  for (int i=0; xylubv(); ++xylubv, ++i) {
218  ub[i] = xylubv.val();
219  if (xlv() && xylubv.val()==xlv.val()) {
220  b.set(2*i);
221  ++xlv;
222  }
223  if (xuv() && xylubv.val()==xuv.val()) {
224  b.set(2*i+1);
225  ++xuv;
226  }
227  if (ylv() && xylubv.val()==ylv.val()) {
228  b.set(2*xsize+2*i);
229  ++ylv;
230  }
231  if (yuv() && xylubv.val()==yuv.val()) {
232  b.set(2*xsize+2*i+1);
233  ++yuv;
234  }
235  }
236  }
237 
238  template<class View0, class View1, bool strict>
240  Lq<View0,View1,strict>::Lq(Home home, View0 x, View1 y)
241  : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y) {}
242 
243  template<class View0, class View1, bool strict>
245  Lq<View0,View1,strict>::Lq(Space& home, bool share, Lq& p)
246  : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,share,p) {}
247 
248  template<class View0, class View1, bool strict>
249  ExecStatus
250  Lq<View0,View1,strict>::post(Home home, View0 x, View1 y) {
251  if (strict)
252  GECODE_ME_CHECK(y.cardMin(home,1));
253  (void) new (home) Lq(home,x,y);
254  return ES_OK;
255  }
256 
257  template<class View0, class View1, bool strict>
258  Actor*
259  Lq<View0,View1,strict>::copy(Space& home, bool share) {
260  return new (home) Lq(home,share,*this);
261  }
262 
263  template<class View0, class View1, bool strict>
264  ExecStatus
266  if ( (!strict) && x1.cardMax()==0) {
267  GECODE_ME_CHECK(x0.cardMax(home,0));
268  }
269 
270  if (x0.cardMax()==0) {
271  return home.ES_SUBSUMED(*this);
272  }
273 
274  if (x0.glbMin() < x1.lubMin())
275  return ES_FAILED;
276  if (x1.glbMin() < x0.lubMin())
277  return home.ES_SUBSUMED(*this);
278 
279  bool assigned = x0.assigned() && x1.assigned();
280 
281  Region re(home);
282  CharacteristicSets cs(re,x0,x1);
283 
284  /*
285  * State 1
286  *
287  */
288  int i=0;
289  int firsti=0;
290  int n=cs.size();
291  while ((i<n) && cs.xmin(i) == cs.ymax(i)) {
292  // case: =, >=
293  GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
294  GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
295  i++;
296  }
297 
298  if (i == n) {// case: $
299  if (strict) {
300  return ES_FAILED;
301  } else {
302  GECODE_ES_CHECK(cs.prune(home,x0,x1));
303  return home.ES_SUBSUMED(*this);
304  }
305  }
306 
307  // Possible cases left: <, <=, > (yields failure), ?
308  GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
309  GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
310 
311  if (cs.xmax(i) < cs.ymin(i)) { // case: < (after tell)
312  GECODE_ES_CHECK(cs.prune(home,x0,x1));
313  return home.ES_SUBSUMED(*this);
314  }
315 
316  firsti=i;
317 
318  /*
319  * State 2
320  * prefix: (?|<=)
321  *
322  */
323  i++;
324 
325  while ((i < n) &&
326  (cs.xmin(i) == cs.ymax(i)) &&
327  (cs.xmax(i) == cs.ymin(i))) { // case: =
328  i++;
329  }
330 
331  if (i == n) { // case: $
332  if (strict)
333  goto rewrite_le;
334  else
335  goto rewrite_lq;
336  }
337 
338  if (cs.xmax(i) < cs.ymin(i)) // case: <
339  goto rewrite_lq;
340 
341  if (cs.xmin(i) > cs.ymax(i)) // case: >
342  goto rewrite_le;
343 
344  if (cs.xmax(i) <= cs.ymin(i)) {
345  // case: <= (invariant: not =, <)
346  /*
347  * State 3
348  * prefix: (?|<=),<=
349  *
350  */
351  i++;
352 
353  while ((i < n) && (cs.xmax(i) == cs.ymin(i))) {// case: <=, =
354  i++;
355  }
356 
357  if (i == n) { // case: $
358  if (strict) {
359  GECODE_ES_CHECK(cs.prune(home,x0,x1));
360  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
361  } else {
362  goto rewrite_lq;
363  }
364  }
365 
366  if (cs.xmax(i) < cs.ymin(i)) // case: <
367  goto rewrite_lq;
368 
369  GECODE_ES_CHECK(cs.prune(home,x0,x1));
370  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
371  }
372 
373  if (cs.xmin(i) >= cs.ymax(i)) {
374  // case: >= (invariant: not =, >)
375  /*
376  * State 4
377  * prefix: (?|<=) >=
378  *
379  */
380  i++;
381 
382  while ((i < n) && (cs.xmin(i) == cs.ymax(i))) {
383  // case: >=, =
384  i++;
385  }
386 
387  if (i == n) { // case: $
388  if (strict) {
389  goto rewrite_le;
390  } else {
391  GECODE_ES_CHECK(cs.prune(home,x0,x1));
392  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
393  }
394  }
395 
396  if (cs.xmin(i) > cs.ymax(i)) // case: >
397  goto rewrite_le;
398 
399  GECODE_ES_CHECK(cs.prune(home,x0,x1));
400  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
401  }
402 
403  GECODE_ES_CHECK(cs.prune(home,x0,x1));
404  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
405 
406  rewrite_le:
407  GECODE_ME_CHECK(cs.xlq(firsti,false));
408  GECODE_ME_CHECK(cs.ygq(firsti,true));
409  GECODE_ES_CHECK(cs.prune(home,x0,x1));
410  return home.ES_SUBSUMED(*this);
411  rewrite_lq:
412  GECODE_ES_CHECK(cs.prune(home,x0,x1));
413  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
414  }
415 
416 }}}
417 
418 // STATISTICS: set-prop
bool get(unsigned int i) const
Access value at bit i.
int size(void) const
Return size of combined upper bounds.
Definition: lq.hpp:167
CSIter(void)
Default constructor.
Definition: lq.hpp:85
const Gecode::ModEvent ME_SET_FAILED
Domain operation has resulted in failure.
Definition: var-type.hpp:138
int yoff
Offset for each element (0=lower bound, 1=upper bound)
Definition: lq.hpp:77
Value iterator for characteristic function.
Definition: lq.hpp:68
bool xmin(int i) const
Return minimum of element i for variable x.
Definition: lq.hpp:104
ExecStatus ES_SUBSUMED(Propagator &p)
Definition: core.hpp:2973
int val(void) const
Value of current iterator position.
Definition: lq.hpp:95
void clear(unsigned int i)
Clear bit i.
bool xmax(int i) const
Return maximum of element i for variable x.
Definition: lq.hpp:106
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition: region.hpp:326
Support::BitSetBase b
Storage for the characteristic functions.
Definition: lq.hpp:48
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition: lq.hpp:265
Basic bitset support.
int ModEvent
Type for modification events.
Definition: core.hpp:146
Propagator for set less than or equal
Definition: rel.hh:203
bool yum
Whether upper bound of y was updated.
Definition: lq.hpp:58
Range iterator for the greatest lower bound.
Definition: var-imp.hpp:363
CSIter(CharacteristicSets &cs0, int xoff0, int yoff0)
Constructor.
Definition: lq.hpp:87
Handle to region.
Definition: region.hpp:61
CharacteristicSets * cs
Pointer to the underlying set.
Definition: lq.hpp:71
int xoff
Offset from start of bitset.
Definition: lq.hpp:75
Computation spaces.
Definition: core.hpp:1362
Range iterator for the least upper bound.
Definition: var-imp.hpp:321
Base-class for both propagators and branchers.
Definition: core.hpp:666
ModEvent xlq(int i, bool j)
Update upper bound of to j.
Definition: lq.hpp:122
#define GECODE_ES_CHECK(es)
Check whether execution status es is failed or subsumed, and forward failure or subsumption.
Definition: macros.hpp:84
static ExecStatus post(Home home, View0, View1)
Post propagator .
Definition: lq.hpp:250
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
Gecode::IntArgs i(4, 1, 2, 3, 4)
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
void reset(void)
Reset iterator to start.
void set(int i, bool j)
Set bit i to value j.
Definition: lq.hpp:60
Execution has resulted in failure.
Definition: core.hpp:525
bool ymin(int i) const
Return minimum of element i for variable y.
Definition: lq.hpp:108
void operator++(void)
Move iterator to next element.
Definition: lq.hpp:79
void ymin(int i, bool j)
Set minimum of element i for variable y to j.
Definition: lq.hpp:117
Representation of the characteristic functions of two sets.
Definition: lq.hpp:43
ModEvent ygq(int i, bool j)
Update lower bound of to j.
Definition: lq.hpp:155
Value iterator from range iterator.
Range iterator from value iterator.
unsigned int size(I &i)
Size of all ranges of range iterator i.
Lq(Space &home, bool share, Lq &p)
Constructor for cloning p.
Definition: lq.hpp:245
virtual Actor * copy(Space &home, bool)
Copy propagator during cloning.
Definition: lq.hpp:259
void init(A &a, unsigned int s, bool setbits=false)
Initialize for s bits and allocator a (only after default constructor)
void set(unsigned int i)
Set bit i.
const Gecode::ModEvent ME_SET_NONE
Domain operation has not changed domain.
Definition: var-type.hpp:140
unsigned int i
Current position.
Definition: lq.hpp:73
CharacteristicSets(Region &re, View0 x, View1 y)
Constructor.
Definition: lq.hpp:198
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition: macros.hpp:45
bool operator()(void) const
Test if iterator is finished.
Definition: lq.hpp:93
const Gecode::PropCond PC_SET_ANY
Propagate when any bound or the cardinality of a view changes.
Definition: var-type.hpp:248
ExecStatus prune(Space &home, View0 x, View1 y)
Prune x and y using computed bounds.
Definition: lq.hpp:171
Range iterator for computing union (binary)
ModEvent ylq(int i, bool j)
Update upper bound of to j.
Definition: lq.hpp:144
Node * x
Pointer to corresponding Boolean expression node.
Definition: bool-expr.cpp:253
bool xlm
Whether lower bound of x was updated.
Definition: lq.hpp:52
Mixed binary propagator.
Definition: propagator.hpp:203
ModEvent xgq(int i, bool j)
Update lower bound of to j.
Definition: lq.hpp:133
void ymax(int i, bool j)
Set maximum of element i for variable y to j.
Definition: lq.hpp:119
Range iterator cache
ExecStatus
Definition: core.hpp:523
bool assigned(View x, int v)
Whether x is assigned to value v.
Definition: single.hpp:47
#define forceinline
Definition: config.hpp:132
int * ub
Elements in the combined upper bounds.
Definition: lq.hpp:50
Execution is okay.
Definition: core.hpp:527
Propagation has not computed fixpoint.
Definition: core.hpp:526
int val(void) const
Return current value.
void xmax(int i, bool j)
Set maximum of element i for variable x to j.
Definition: lq.hpp:115
unsigned int xsize
Size of the combined upper bounds.
Definition: lq.hpp:46
Gecode toplevel namespace
void xmin(int i, bool j)
Set minimum of element i for variable x to j.
Definition: lq.hpp:113
int ModEventDelta
Modification event deltas.
Definition: core.hpp:173
Home class for posting propagators
Definition: core.hpp:717
bool xum
Whether upper bound of x was updated.
Definition: lq.hpp:54
bool ylm
Whether lower bound of y was updated.
Definition: lq.hpp:56
bool ymax(int i) const
Return maximum of element i for variable y.
Definition: lq.hpp:110