this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2006
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.org
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34namespace Gecode { namespace Int {
35
36 /*
37 * Creation of new variable implementations
38 *
39 */
40 forceinline
41 BoolVarImp::BoolVarImp(int n) {
42 assert(bits() == 0);
43 bits() |= (n << 1) | n;
44 }
45 forceinline
46 BoolVarImp::BoolVarImp(Space& home, int min, int max)
47 : BoolVarImpBase(home) {
48 assert(bits() == 0);
49 bits() |= (max << 1) | min;
50 }
51
52
53 /*
54 * Operations on Boolean variable implementations
55 *
56 */
57 forceinline BoolStatus
58 BoolVarImp::status(void) const {
59 return bits() & 3;
60 }
61 forceinline int
62 BoolVarImp::min(void) const {
63 return static_cast<int>(bits() & 1);
64 }
65 forceinline int
66 BoolVarImp::max(void) const {
67 return static_cast<int>((bits() & 2) >> 1);
68 }
69 forceinline int
70 BoolVarImp::med(void) const {
71 return min();
72 }
73
74 forceinline int
75 BoolVarImp::val(void) const {
76 assert(status() != NONE);
77 return min();
78 }
79
80 forceinline bool
81 BoolVarImp::range(void) const {
82 return true;
83 }
84 forceinline bool
85 BoolVarImp::assigned(void) const {
86 return status() != NONE;
87 }
88
89
90 forceinline unsigned int
91 BoolVarImp::width(void) const {
92 return assigned() ? 1U : 2U;
93 }
94
95 forceinline unsigned int
96 BoolVarImp::size(void) const {
97 return assigned() ? 1U : 2U;
98 }
99
100 forceinline unsigned int
101 BoolVarImp::regret_min(void) const {
102 return assigned() ? 1U : 0U;
103 }
104 forceinline unsigned int
105 BoolVarImp::regret_max(void) const {
106 return assigned() ? 1U : 0U;
107 }
108
109
110
111 /*
112 * Tests
113 *
114 */
115
116 forceinline bool
117 BoolVarImp::in(int n) const {
118 return (n >= min()) && (n <= max());
119 }
120 forceinline bool
121 BoolVarImp::in(long long int n) const {
122 return (n >= min()) && (n <= max());
123 }
124
125
126 /*
127 * Boolean domain tests
128 *
129 */
130 forceinline bool
131 BoolVarImp::zero(void) const {
132 return status() < NONE;
133 }
134 forceinline bool
135 BoolVarImp::one(void) const {
136 return status() > NONE;
137 }
138 forceinline bool
139 BoolVarImp::none(void) const {
140 return status() == NONE;
141 }
142
143
144 /*
145 * Support for delta information
146 *
147 */
148 forceinline ModEvent
149 BoolVarImp::modevent(const Delta&) {
150 return ME_BOOL_VAL;
151 }
152 forceinline int
153 BoolVarImp::min(const Delta& d) {
154 return static_cast<const IntDelta&>(d).min();
155 }
156 forceinline int
157 BoolVarImp::max(const Delta& d) {
158 return static_cast<const IntDelta&>(d).min();
159 }
160 forceinline unsigned int
161 BoolVarImp::width(const Delta& d) {
162 return static_cast<const IntDelta&>(d).width();
163 }
164 forceinline bool
165 BoolVarImp::any(const Delta&) {
166 return false;
167 }
168 forceinline bool
169 BoolVarImp::zero(const Delta& d) {
170 return static_cast<const IntDelta&>(d).min() != 0;
171 }
172 forceinline bool
173 BoolVarImp::one(const Delta& d) {
174 return static_cast<const IntDelta&>(d).min() == 0;
175 }
176
177
178 /*
179 * Boolean tell operations
180 *
181 */
182 forceinline ModEvent
183 BoolVarImp::zero(Space& home) {
184 if (one()) return ME_BOOL_FAILED;
185 if (zero()) return ME_BOOL_NONE;
186 return zero_none(home);
187 }
188 forceinline ModEvent
189 BoolVarImp::one(Space& home) {
190 if (one()) return ME_BOOL_NONE;
191 if (zero()) return ME_BOOL_FAILED;
192 return one_none(home);
193 }
194
195
196 /*
197 * Tell operations
198 *
199 */
200 forceinline ModEvent
201 BoolVarImp::gq(Space& home, int n) {
202 if (n <= 0) return ME_INT_NONE;
203 if (n > 1) return fail(home);
204 return one(home);
205 }
206 forceinline ModEvent
207 BoolVarImp::gq(Space& home, long long int n) {
208 if (n <= 0) return ME_INT_NONE;
209 if (n > 1) return fail(home);
210 return one(home);
211 }
212
213 forceinline ModEvent
214 BoolVarImp::lq(Space& home, int n) {
215 if (n < 0) return fail(home);
216 if (n >= 1) return ME_INT_NONE;
217 return zero(home);
218 }
219 forceinline ModEvent
220 BoolVarImp::lq(Space& home, long long int n) {
221 if (n < 0) return fail(home);
222 if (n >= 1) return ME_INT_NONE;
223 return zero(home);
224 }
225
226 forceinline ModEvent
227 BoolVarImp::eq(Space& home, int n) {
228 if ((n < 0) || (n > 1)) return fail(home);
229 return (n == 0) ? zero(home): one(home);
230 }
231 forceinline ModEvent
232 BoolVarImp::eq(Space& home, long long int n) {
233 if ((n < 0) || (n > 1)) return fail(home);
234 return (n == 0) ? zero(home): one(home);
235 }
236
237 forceinline ModEvent
238 BoolVarImp::nq(Space& home, int n) {
239 if ((n < 0) || (n > 1)) return ME_INT_NONE;
240 return (n == 0) ? one(home): zero(home);
241 }
242 forceinline ModEvent
243 BoolVarImp::nq(Space& home, long long int n) {
244 if ((n < 0) || (n > 1)) return ME_INT_NONE;
245 return (n == 0) ? one(home): zero(home);
246 }
247
248
249 /*
250 * Copying a variable
251 *
252 */
253
254 forceinline
255 BoolVarImp::BoolVarImp(Space& home, BoolVarImp& x)
256 : BoolVarImpBase(home,x) {}
257 forceinline BoolVarImp*
258 BoolVarImp::copy(Space& home) {
259 if (copied())
260 return static_cast<BoolVarImp*>(forward());
261 else if (zero())
262 return &s_zero;
263 else if (one())
264 return &s_one;
265 else
266 return new (home) BoolVarImp(home,*this);
267 }
268
269
270 /*
271 * Iterator-based domain operations
272 *
273 */
274 template<class I>
275 forceinline ModEvent
276 BoolVarImp::narrow_r(Space& home, I& i, bool) {
277 // Is new domain empty?
278 if (!i())
279 return fail(home);
280 assert((i.min() == 0) || (i.min() == 1));
281 assert((i.max() == 0) || (i.max() == 1));
282 if (i.max() == 0) {
283 assert(!one());
284 // Assign domain to be zero (domain cannot be one)
285 return zero(home);
286 }
287 if (i.min() == 1) {
288 // Assign domain to be one (domain cannot be zero)
289 assert(!zero());
290 return one(home);
291 }
292 assert(none());
293 return ME_INT_NONE;
294 }
295 template<class I>
296 forceinline ModEvent
297 BoolVarImp::inter_r(Space& home, I& i, bool) {
298 // Skip all ranges that are too small
299 while (i() && (i.max() < 0))
300 ++i;
301 // Is new domain empty?
302 if (!i() || (i.min() > 1))
303 return fail(home);
304 assert(i.min() <= 1);
305 if (i.min() == 1)
306 return one(home);
307 if (i.max() == 0)
308 return zero(home);
309 assert((i.min() <= 0) && (i.max() >= 1));
310 return ME_INT_NONE;
311 }
312 template<class I>
313 forceinline ModEvent
314 BoolVarImp::minus_r(Space& home, I& i, bool) {
315 // Skip all ranges that are too small
316 while (i() && (i.max() < 0))
317 ++i;
318 // Is new domain empty?
319 if (!i() || (i.min() > 1))
320 return ME_INT_NONE;
321 assert(i.min() <= 1);
322 if (i.min() == 1)
323 return zero(home);
324 if (i.max() == 0)
325 return one(home);
326 assert((i.min() <= 0) && (i.max() >= 1));
327 return fail(home);
328 }
329
330 template<class I>
331 forceinline ModEvent
332 BoolVarImp::narrow_v(Space& home, I& i, bool) {
333 if (!i())
334 return fail(home);
335 if (!none())
336 return ME_INT_NONE;
337 if (i.val() == 0) {
338 do {
339 ++i;
340 } while (i() && (i.val() == 0));
341 if (!i())
342 return zero_none(home);
343 return ME_INT_NONE;
344 } else {
345 assert(i.val() == 1);
346 return one_none(home);
347 }
348 }
349 template<class I>
350 forceinline ModEvent
351 BoolVarImp::inter_v(Space& home, I& i, bool) {
352 while (i() && (i.val() < 0))
353 ++i;
354 if (!i() || (i.val() > 1))
355 return fail(home);
356 if (i.val() == 0) {
357 do {
358 ++i;
359 } while (i() && (i.val() == 0));
360 if (!i() || (i.val() > 1))
361 return zero(home);
362 return ME_INT_NONE;
363 } else {
364 assert(i.val() == 1);
365 return one(home);
366 }
367 }
368 template<class I>
369 forceinline ModEvent
370 BoolVarImp::minus_v(Space& home, I& i, bool) {
371 while (i() && (i.val() < 0))
372 ++i;
373 if (!i() || (i.val() > 1))
374 return ME_INT_NONE;
375 if (i.val() == 0) {
376 do {
377 ++i;
378 } while (i() && (i.val() == 0));
379 if (!i() || (i.val() > 1))
380 return one(home);
381 return fail(home);
382 } else {
383 assert(i.val() == 1);
384 return zero(home);
385 }
386 }
387
388
389
390 /*
391 * Dependencies
392 *
393 */
394 forceinline void
395 BoolVarImp::cancel(Space& home, Propagator& p, PropCond) {
396 BoolVarImpBase::cancel(home,p,PC_BOOL_VAL);
397 }
398
399 forceinline void
400 BoolVarImp::cancel(Space& home, Advisor& a, bool fail) {
401 BoolVarImpBase::cancel(home,a,fail);
402 }
403
404 forceinline void
405 BoolVarImp::schedule(Space& home, Propagator& p, ModEvent) {
406 BoolVarImpBase::schedule(home,p,ME_BOOL_VAL);
407 }
408
409 forceinline ModEventDelta
410 BoolVarImp::med(ModEvent me) {
411 return BoolVarImpBase::med(me);
412 }
413
414}}
415
416// STATISTICS: int-var