Generated on Thu Apr 5 2018 19:44:19 for Gecode by doxygen 1.8.13
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$ by $Author$
11  * $Revision$
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  bool get(unsigned int i) const;
62  void set(unsigned int i, bool j);
63 
65  class CSIter {
66  public:
70  unsigned int i;
72  unsigned int xoff;
74  unsigned int yoff;
76  void operator++ (void);
78  CSIter(void);
80  CSIter(CharacteristicSets& cs0, unsigned int xoff0, unsigned int yoff0);
82  bool operator() (void) const;
84  int val(void) const;
85  };
86 
87  public:
89  template<class View0, class View1>
90  CharacteristicSets(Region& re, View0 x, View1 y);
91 
93  bool xmin(unsigned int i) const;
95  bool xmax(unsigned int i) const;
97  bool ymin(unsigned int i) const;
99  bool ymax(unsigned int i) const;
100 
102  void xmin(unsigned int i, bool j);
104  void xmax(unsigned int i, bool j);
106  void ymin(unsigned int i, bool j);
108  void ymax(unsigned int i, bool j);
109 
111  ModEvent xlq(unsigned int i, bool j);
113  ModEvent xgq(unsigned int i, bool j);
115  ModEvent ylq(unsigned int i, bool j);
117  ModEvent ygq(unsigned int i, bool j);
118 
120  unsigned int size(void) const;
121 
123  template<class View0, class View1>
124  ExecStatus prune(Space& home, View0 x, View1 y);
125 
126  };
127 
128 
129  forceinline bool
130  CharacteristicSets::get(unsigned int i) const {
131  return b.get(i);
132  }
133  forceinline void
134  CharacteristicSets::set(unsigned int i, bool j) {
135  if (j)
136  b.set(i);
137  else
138  b.clear(i);
139  }
140  forceinline unsigned int
142  return xsize;
143  }
144 
149  unsigned int xoff0, unsigned int yoff0)
150  : cs(&cs0), i(0), xoff(xoff0), yoff(yoff0) {
151  while ((i < cs->xsize) && !cs->get(xoff+2*i+yoff))
152  i++;
153  }
154  forceinline void
156  i++;
157  while ((i < cs->xsize) && !cs->get(xoff+2*i+yoff))
158  i++;
159  }
160  forceinline bool
162  return i<cs->xsize;
163  }
164  forceinline int
166  return cs->ub[i];
167  }
168 
169 
170  forceinline bool
171  CharacteristicSets::xmin(unsigned int i) const {
172  return get(2*i);
173  }
174  forceinline bool
175  CharacteristicSets::xmax(unsigned int i) const {
176  return get(2*i+1);
177  }
178  forceinline bool
179  CharacteristicSets::ymin(unsigned int i) const {
180  return get(2*xsize+2*i);
181  }
182  forceinline bool
183  CharacteristicSets::ymax(unsigned int i) const {
184  return get(2*xsize+2*i+1);
185  }
186 
187  forceinline void
188  CharacteristicSets::xmin(unsigned int i, bool j) {
189  set(2*i,j);
190  }
191  forceinline void
192  CharacteristicSets::xmax(unsigned int i, bool j) {
193  set(2*i+1,j);
194  }
195  forceinline void
196  CharacteristicSets::ymin(unsigned int i, bool j) {
197  set(2*xsize+2*i,j);
198  }
199  forceinline void
200  CharacteristicSets::ymax(unsigned int i, bool j) {
201  set(2*xsize+2*i+1,j);
202  }
203 
205  CharacteristicSets::xlq(unsigned int i, bool j) {
206  if (!j) {
207  if (xmin(i)) return ME_SET_FAILED;
208  if (xmax(i)) {
209  xmax(i,false);
210  xum=true;
211  }
212  }
213  return ME_SET_NONE;
214  }
216  CharacteristicSets::xgq(unsigned int i, bool j) {
217  if (j) {
218  if (!xmax(i)) return ME_SET_FAILED;
219  if (!xmin(i)) {
220  xmin(i,true);
221  xlm=true;
222  }
223  }
224  return ME_SET_NONE;
225  }
227  CharacteristicSets::ylq(unsigned int i, bool j) {
228  if (!j) {
229  if (ymin(i)) return ME_SET_FAILED;
230  if (ymax(i)) {
231  ymax(i,false);
232  yum=true;
233  }
234  }
235  return ME_SET_NONE;
236  }
238  CharacteristicSets::ygq(unsigned int i, bool j) {
239  if (j) {
240  if (!ymax(i)) return ME_SET_FAILED;
241  if (!ymin(i)) {
242  ymin(i,true);
243  ylm=true;
244  }
245  }
246  return ME_SET_NONE;
247  }
248 
249  template<class View0, class View1>
251  CharacteristicSets::prune(Space& home, View0 x, View1 y) {
252  if (xlm) {
253  CSIter i(*this,0,0);
255  GECODE_ME_CHECK(x.includeI(home,ir));
256  }
257  if (xum) {
258  CSIter i(*this,0,1);
260  GECODE_ME_CHECK(x.intersectI(home,ir));
261  }
262  if (ylm) {
263  CSIter i(*this,2*xsize,0);
265  GECODE_ME_CHECK(y.includeI(home,ir));
266  }
267  if (yum) {
268  CSIter i(*this,2*xsize,1);
270  GECODE_ME_CHECK(y.intersectI(home,ir));
271  }
272  return ES_OK;
273  }
274 
275  template<class View0, class View1>
278  : xlm(false), xum(false), ylm(false), yum(false) {
279  LubRanges<View0> xlub(x);
280  LubRanges<View1> ylub(y);
282  Iter::Ranges::Cache xylubc(re,xylub);
283  xsize = Iter::Ranges::size(xylubc);
284  b.init(re,4*xsize);
285  ub = re.alloc<int>(xsize);
286  xylubc.reset();
288  LubRanges<View0> xur(x);
289  GlbRanges<View0> xlr(x);
290  LubRanges<View1> yur(y);
291  GlbRanges<View1> ylr(y);
296  for (unsigned int i=0; xylubv(); ++xylubv, ++i) {
297  ub[i] = xylubv.val();
298  if (xlv() && xylubv.val()==xlv.val()) {
299  b.set(2*i);
300  ++xlv;
301  }
302  if (xuv() && xylubv.val()==xuv.val()) {
303  b.set(2*i+1);
304  ++xuv;
305  }
306  if (ylv() && xylubv.val()==ylv.val()) {
307  b.set(2*xsize+2*i);
308  ++ylv;
309  }
310  if (yuv() && xylubv.val()==yuv.val()) {
311  b.set(2*xsize+2*i+1);
312  ++yuv;
313  }
314  }
315  }
316 
317  template<class View0, class View1, bool strict>
319  Lq<View0,View1,strict>::Lq(Home home, View0 x, View1 y)
320  : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,x,y) {}
321 
322  template<class View0, class View1, bool strict>
325  : MixBinaryPropagator<View0,PC_SET_ANY,View1,PC_SET_ANY>(home,p) {}
326 
327  template<class View0, class View1, bool strict>
328  ExecStatus
329  Lq<View0,View1,strict>::post(Home home, View0 x, View1 y) {
330  if (strict)
331  GECODE_ME_CHECK(y.cardMin(home,1));
332  if (same(x,y))
333  return strict ? ES_FAILED : ES_OK;
334  (void) new (home) Lq(home,x,y);
335  return ES_OK;
336  }
337 
338  template<class View0, class View1, bool strict>
339  Actor*
341  return new (home) Lq(home,*this);
342  }
343 
344  template<class View0, class View1, bool strict>
345  ExecStatus
347  if ( (!strict) && x1.cardMax()==0) {
348  GECODE_ME_CHECK(x0.cardMax(home,0));
349  }
350 
351  if (x0.cardMax()==0) {
352  return home.ES_SUBSUMED(*this);
353  }
354 
355  if (x0.glbMin() < x1.lubMin())
356  return ES_FAILED;
357  if (x1.glbMin() < x0.lubMin())
358  return home.ES_SUBSUMED(*this);
359 
360  bool assigned = x0.assigned() && x1.assigned();
361 
362  Region re;
363  CharacteristicSets cs(re,x0,x1);
364 
365  /*
366  * State 1
367  *
368  */
369  unsigned int i=0;
370  unsigned int firsti=0;
371  unsigned int n=cs.size();
372  while ((i<n) && (cs.xmin(i) == cs.ymax(i))) {
373  // case: =, >=
374  GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
375  GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
376  i++;
377  }
378 
379  if (i == n) {// case: $
380  if (strict) {
381  return ES_FAILED;
382  } else {
383  GECODE_ES_CHECK(cs.prune(home,x0,x1));
384  return home.ES_SUBSUMED(*this);
385  }
386  }
387 
388  // Possible cases left: <, <=, > (yields failure), ?
389  GECODE_ME_CHECK(cs.xlq(i,cs.ymax(i)));
390  GECODE_ME_CHECK(cs.ygq(i,cs.xmin(i)));
391 
392  if (cs.xmax(i) < cs.ymin(i)) { // case: < (after tell)
393  GECODE_ES_CHECK(cs.prune(home,x0,x1));
394  return home.ES_SUBSUMED(*this);
395  }
396 
397  firsti=i;
398 
399  /*
400  * State 2
401  * prefix: (?|<=)
402  *
403  */
404  i++;
405 
406  while ((i < n) &&
407  (cs.xmin(i) == cs.ymax(i)) &&
408  (cs.xmax(i) == cs.ymin(i))) { // case: =
409  i++;
410  }
411 
412  if (i == n) { // case: $
413  if (strict)
414  goto rewrite_le;
415  else
416  goto rewrite_lq;
417  }
418 
419  if (cs.xmax(i) < cs.ymin(i)) // case: <
420  goto rewrite_lq;
421 
422  if (cs.xmin(i) > cs.ymax(i)) // case: >
423  goto rewrite_le;
424 
425  if (cs.xmax(i) <= cs.ymin(i)) {
426  // case: <= (invariant: not =, <)
427  /*
428  * State 3
429  * prefix: (?|<=),<=
430  *
431  */
432  i++;
433 
434  while ((i < n) && (cs.xmax(i) == cs.ymin(i))) {// case: <=, =
435  i++;
436  }
437 
438  if (i == n) { // case: $
439  if (strict) {
440  GECODE_ES_CHECK(cs.prune(home,x0,x1));
441  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
442  } else {
443  goto rewrite_lq;
444  }
445  }
446 
447  if (cs.xmax(i) < cs.ymin(i)) // case: <
448  goto rewrite_lq;
449 
450  GECODE_ES_CHECK(cs.prune(home,x0,x1));
451  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
452  }
453 
454  if (cs.xmin(i) >= cs.ymax(i)) {
455  // case: >= (invariant: not =, >)
456  /*
457  * State 4
458  * prefix: (?|<=) >=
459  *
460  */
461  i++;
462 
463  while ((i < n) && (cs.xmin(i) == cs.ymax(i))) {
464  // case: >=, =
465  i++;
466  }
467 
468  if (i == n) { // case: $
469  if (strict) {
470  goto rewrite_le;
471  } else {
472  GECODE_ES_CHECK(cs.prune(home,x0,x1));
473  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
474  }
475  }
476 
477  if (cs.xmin(i) > cs.ymax(i)) // case: >
478  goto rewrite_le;
479 
480  GECODE_ES_CHECK(cs.prune(home,x0,x1));
481  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
482  }
483 
484  GECODE_ES_CHECK(cs.prune(home,x0,x1));
485  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
486 
487  rewrite_le:
488  GECODE_ME_CHECK(cs.xlq(firsti,false));
489  GECODE_ME_CHECK(cs.ygq(firsti,true));
490  GECODE_ES_CHECK(cs.prune(home,x0,x1));
491  return home.ES_SUBSUMED(*this);
492  rewrite_lq:
493  GECODE_ES_CHECK(cs.prune(home,x0,x1));
494  return assigned ? home.ES_SUBSUMED(*this) : ES_NOFIX;
495  }
496 
497 }}}
498 
499 // STATISTICS: set-prop
bool get(unsigned int i) const
Access value at bit i.
CSIter(void)
Default constructor.
Definition: lq.hpp:146
const Gecode::ModEvent ME_SET_FAILED
Domain operation has resulted in failure.
Definition: var-type.hpp:138
Value iterator for characteristic function.
Definition: lq.hpp:65
ExecStatus ES_SUBSUMED(Propagator &p)
Definition: core.hpp:3433
unsigned int yoff
Offset for each element (0=lower bound, 1=upper bound)
Definition: lq.hpp:74
void clear(unsigned int i)
Clear bit i.
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition: region.hpp:384
virtual Actor * copy(Space &home)
Copy propagator during cloning.
Definition: lq.hpp:340
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:346
Basic bitset support.
int ModEvent
Type for modification events.
Definition: core.hpp:64
Propagator for set less than or equal
Definition: rel.hh:212
bool yum
Whether upper bound of y was updated.
Definition: lq.hpp:58
ModEvent xgq(unsigned int i, bool j)
Update lower bound of to j.
Definition: lq.hpp:216
Range iterator for the greatest lower bound.
Definition: var-imp.hpp:363
unsigned int size(void) const
Return size of combined upper bounds.
Definition: lq.hpp:141
bool operator()(void) const
Test if iterator is finished.
Definition: lq.hpp:161
Handle to region.
Definition: region.hpp:57
bool get(unsigned int i) const
Get bit i.
Definition: lq.hpp:130
#define forceinline
Definition: config.hpp:182
CharacteristicSets * cs
Pointer to the underlying set.
Definition: lq.hpp:68
Computation spaces.
Definition: core.hpp:1668
int val(void) const
Return current value.
Range iterator for the least upper bound.
Definition: var-imp.hpp:321
Base-class for both propagators and branchers.
Definition: core.hpp:620
bool xmax(unsigned int i) const
Return maximum of element i for variable x.
Definition: lq.hpp:175
#define GECODE_ES_CHECK(es)
Check whether execution status es is failed or subsumed, and forward failure or subsumption.
Definition: macros.hpp:95
int val(void) const
Value of current iterator position.
Definition: lq.hpp:165
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
void set(unsigned int i, bool j)
Set bit i to value j.
Definition: lq.hpp:134
Gecode::IntArgs i(4, 1, 2, 3, 4)
bool ymin(unsigned int i) const
Return minimum of element i for variable y.
Definition: lq.hpp:179
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
void reset(void)
Reset iterator to start.
Execution has resulted in failure.
Definition: core.hpp:466
bool xmin(unsigned int i) const
Return minimum of element i for variable x.
Definition: lq.hpp:171
void operator++(void)
Move iterator to next element.
Definition: lq.hpp:155
bool same(VX, VY)
Test whether two views are in fact the same.
Definition: common.hpp:61
Representation of the characteristic functions of two sets.
Definition: lq.hpp:43
Value iterator from range iterator.
Range iterator from value iterator.
unsigned int size(I &i)
Size of all ranges of range iterator i.
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.
ModEvent xlq(unsigned int i, bool j)
Update upper bound of to j.
Definition: lq.hpp:205
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:70
CharacteristicSets(Region &re, View0 x, View1 y)
Constructor.
Definition: lq.hpp:277
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition: macros.hpp:56
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:251
Range iterator for computing union (binary)
ModEvent ylq(unsigned int i, bool j)
Update upper bound of to j.
Definition: lq.hpp:227
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:769
bool xlm
Whether lower bound of x was updated.
Definition: lq.hpp:52
Mixed binary propagator.
Definition: pattern.hpp:208
Range iterator cache
ExecStatus
Definition: core.hpp:464
bool assigned(View x, int v)
Whether x is assigned to value v.
Definition: single.hpp:47
static ExecStatus post(Home home, View0 x, View1 y)
Post propagator .
Definition: lq.hpp:329
int * ub
Elements in the combined upper bounds.
Definition: lq.hpp:50
Post propagator for SetVar x
Definition: set.hh:769
Execution is okay.
Definition: core.hpp:468
Propagation has not computed fixpoint.
Definition: core.hpp:467
unsigned int xsize
Size of the combined upper bounds.
Definition: lq.hpp:46
Gecode toplevel namespace
bool ymax(unsigned int i) const
Return maximum of element i for variable y.
Definition: lq.hpp:183
ModEvent ygq(unsigned int i, bool j)
Update lower bound of to j.
Definition: lq.hpp:238
Lq(Space &home, Lq &p)
Constructor for cloning p.
Definition: lq.hpp:324
int ModEventDelta
Modification event deltas.
Definition: core.hpp:91
unsigned int xoff
Offset from start of bitset.
Definition: lq.hpp:72
Home class for posting propagators
Definition: core.hpp:846
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