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 { namespace Linear {
35
36 /*
37 * Array of scale Boolean views
38 *
39 */
40 forceinline
41 ScaleBoolArray::ScaleBoolArray(void) {}
42 forceinline
43 ScaleBoolArray::ScaleBoolArray(Space& home, int n) {
44 if (n > 0) {
45 _fst = home.alloc<ScaleBool>(n);
46 _lst = _fst+n;
47 } else {
48 _fst = _lst = nullptr;
49 }
50 }
51 forceinline void
52 ScaleBoolArray::subscribe(Space& home, Propagator& p) {
53 for (ScaleBool* f = _fst; f < _lst; f++)
54 f->x.subscribe(home,p,PC_BOOL_VAL);
55 }
56 forceinline void
57 ScaleBoolArray::cancel(Space& home, Propagator& p) {
58 for (ScaleBool* f = _fst; f < _lst; f++)
59 f->x.cancel(home,p,PC_BOOL_VAL);
60 }
61 forceinline void
62 ScaleBoolArray::reschedule(Space& home, Propagator& p) {
63 for (ScaleBool* f = _fst; f < _lst; f++)
64 f->x.reschedule(home,p,PC_BOOL_VAL);
65 }
66 forceinline void
67 ScaleBoolArray::update(Space& home, ScaleBoolArray& sba) {
68 int n = static_cast<int>(sba._lst - sba._fst);
69 if (n > 0) {
70 _fst = home.alloc<ScaleBool>(n);
71 _lst = _fst+n;
72 for (int i=0; i<n; i++) {
73 _fst[i].a = sba._fst[i].a;
74 _fst[i].x.update(home,sba._fst[i].x);
75 }
76 } else {
77 _fst = _lst = nullptr;
78 }
79 }
80 forceinline ScaleBool*
81 ScaleBoolArray::fst(void) const {
82 return _fst;
83 }
84 forceinline ScaleBool*
85 ScaleBoolArray::lst(void) const {
86 return _lst;
87 }
88 forceinline void
89 ScaleBoolArray::fst(ScaleBool* f) {
90 _fst = f;
91 }
92 forceinline void
93 ScaleBoolArray::lst(ScaleBool* l) {
94 _lst = l;
95 }
96 forceinline bool
97 ScaleBoolArray::empty(void) const {
98 return _fst == _lst;
99 }
100 forceinline int
101 ScaleBoolArray::size(void) const {
102 return static_cast<int>(_lst - _fst);
103 }
104 forceinline bool
105 ScaleBoolArray::ScaleDec::operator ()(const ScaleBool& x,
106 const ScaleBool& y) {
107 return x.a > y.a;
108 }
109
110 inline void
111 ScaleBoolArray::sort(void) {
112 ScaleDec scale_dec;
113 Support::quicksort<ScaleBool,ScaleDec>(fst(), size(), scale_dec);
114 }
115
116
117 /*
118 * Empty array of scale Boolean views
119 *
120 */
121 forceinline
122 EmptyScaleBoolArray::EmptyScaleBoolArray(void) {}
123 forceinline
124 EmptyScaleBoolArray::EmptyScaleBoolArray(Space&, int) {}
125 forceinline void
126 EmptyScaleBoolArray::subscribe(Space&, Propagator&) {}
127 forceinline void
128 EmptyScaleBoolArray::cancel(Space&, Propagator&) {}
129 forceinline void
130 EmptyScaleBoolArray::reschedule(Space&, Propagator&) {}
131 forceinline void
132 EmptyScaleBoolArray::update(Space&, EmptyScaleBoolArray&) {}
133 forceinline ScaleBool*
134 EmptyScaleBoolArray::fst(void) const { return nullptr; }
135 forceinline ScaleBool*
136 EmptyScaleBoolArray::lst(void) const { return nullptr; }
137 forceinline void
138 EmptyScaleBoolArray::fst(ScaleBool*) {}
139 forceinline void
140 EmptyScaleBoolArray::lst(ScaleBool*) {}
141 forceinline bool
142 EmptyScaleBoolArray::empty(void) const { return true; }
143 forceinline int
144 EmptyScaleBoolArray::size(void) const { return 0; }
145 forceinline void
146 EmptyScaleBoolArray::sort(void) {}
147
148
149 /*
150 * Base-class for Boolean constraints with coefficients
151 *
152 */
153
154 template<class SBAP, class SBAN, class VX, PropCond pcx>
155 forceinline
156 LinBoolScale<SBAP,SBAN,VX,pcx>::LinBoolScale(Home home,
157 SBAP& p0, SBAN& n0,
158 VX x0, int c0)
159 : Propagator(home), p(p0), n(n0), x(x0), c(c0) {
160 x.subscribe(home,*this,pcx);
161 p.subscribe(home,*this);
162 n.subscribe(home,*this);
163 }
164
165 template<class SBAP, class SBAN, class VX, PropCond pcx>
166 PropCost
167 LinBoolScale<SBAP,SBAN,VX,pcx>::cost(const Space&,
168 const ModEventDelta&) const {
169 return PropCost::linear(PropCost::LO, p.size() + n.size());
170 }
171
172 template<class SBAP, class SBAN, class VX, PropCond pcx>
173 void
174 LinBoolScale<SBAP,SBAN,VX,pcx>::reschedule(Space& home) {
175 x.reschedule(home,*this,pcx);
176 p.reschedule(home,*this);
177 n.reschedule(home,*this);
178 }
179
180 template<class SBAP, class SBAN, class VX, PropCond pcx>
181 forceinline size_t
182 LinBoolScale<SBAP,SBAN,VX,pcx>::dispose(Space& home) {
183 x.cancel(home,*this,pcx);
184 p.cancel(home,*this);
185 n.cancel(home,*this);
186 (void) Propagator::dispose(home);
187 return sizeof(*this);
188 }
189
190 template<class SBAP, class SBAN, class VX, PropCond pcx>
191 forceinline
192 LinBoolScale<SBAP,SBAN,VX,pcx>::LinBoolScale(Space& home,
193 Propagator& pr,
194 SBAP& p0, SBAN& n0,
195 VX x0, int c0)
196 : Propagator(home,pr), c(c0) {
197 x.update(home,x0);
198 p.update(home,p0);
199 n.update(home,n0);
200 }
201
202 /*
203 * Boolean equality with coefficients
204 *
205 */
206
207 template<class SBAP, class SBAN, class VX>
208 forceinline
209 EqBoolScale<SBAP,SBAN,VX>::EqBoolScale(Home home,
210 SBAP& p, SBAN& n,
211 VX x, int c)
212 : LinBoolScale<SBAP,SBAN,VX,PC_INT_BND>(home,p,n,x,c) {}
213
214 template<class SBAP, class SBAN, class VX>
215 forceinline
216 EqBoolScale<SBAP,SBAN,VX>::EqBoolScale(Space& home,
217 Propagator& pr,
218 SBAP& p, SBAN& n,
219 VX x, int c)
220 : LinBoolScale<SBAP,SBAN,VX,PC_INT_BND>(home,pr,p,n,x,c) {}
221
222 template<class SBAP, class SBAN, class VX>
223 Actor*
224 EqBoolScale<SBAP,SBAN,VX>::copy(Space& home) {
225 if (p.empty()) {
226 EmptyScaleBoolArray ep;
227 if (x.assigned()) {
228 ZeroIntView z;
229 return new (home) EqBoolScale<EmptyScaleBoolArray,SBAN,ZeroIntView>
230 (home,*this,ep,n,z,c+x.val());
231 } else {
232 return new (home) EqBoolScale<EmptyScaleBoolArray,SBAN,VX>
233 (home,*this,ep,n,x,c);
234 }
235 } else if (n.empty()) {
236 EmptyScaleBoolArray en;
237 if (x.assigned()) {
238 ZeroIntView z;
239 return new (home) EqBoolScale<SBAP,EmptyScaleBoolArray,ZeroIntView>
240 (home,*this,p,en,z,c+x.val());
241 } else {
242 return new (home) EqBoolScale<SBAP,EmptyScaleBoolArray,VX>
243 (home,*this,p,en,x,c);
244 }
245 } else {
246 return new (home) EqBoolScale<SBAP,SBAN,VX>(home,*this,p,n,x,c);
247 }
248 }
249
250 template<class SBAP, class SBAN, class VX>
251 ExecStatus
252 EqBoolScale<SBAP,SBAN,VX>::propagate(Space& home, const ModEventDelta& med) {
253 int sl_p = 0; // Lower bound, computed positive
254 int su_n = 0; // Upper bound, computed negative
255 if (BoolView::me(med) == ME_BOOL_VAL) {
256 // Eliminate assigned positive views while keeping order
257 {
258 // Skip not assigned views
259 ScaleBool* f = p.fst();
260 ScaleBool* l = p.lst();
261 while ((f < l) && f->x.none()) {
262 su_n += f->a; f++;
263 }
264 // Copy unassigned views to t
265 ScaleBool* t = f;
266 while (f < l) {
267 if (f->x.one()) {
268 c -= f->a;
269 } else if (f->x.none()) {
270 su_n += f->a; *t = *f; t++;
271 }
272 f++;
273 }
274 p.lst(t);
275 }
276 // Eliminate assigned negative views while keeping order
277 {
278 // Skip not assigned views
279 ScaleBool* f = n.fst();
280 ScaleBool* l = n.lst();
281 while ((f < l) && f->x.none()) {
282 sl_p += f->a; f++;
283 }
284 // Copy unassigned views to t
285 ScaleBool* t = f;
286 while (f < l) {
287 if (f->x.one()) {
288 c += f->a;
289 } else if (f->x.none()) {
290 sl_p += f->a; *t = *f; t++;
291 }
292 f++;
293 }
294 n.lst(t);
295 }
296 } else {
297 for (ScaleBool* f=p.fst(); f<p.lst(); f++)
298 su_n += f->a;
299 for (ScaleBool* f=n.fst(); f<n.lst(); f++)
300 sl_p += f->a;
301 }
302
303 if (p.empty() && n.empty()) {
304 GECODE_ME_CHECK(x.eq(home,-c));
305 return home.ES_SUBSUMED(*this);
306 }
307
308 sl_p += x.max() + c;
309 su_n -= x.min() + c;
310
311 const int MOD_SL = 1 << 0;
312 const int MOD_SU = 1 << 1;
313
314 int mod = MOD_SL | MOD_SU;
315
316 do {
317 if ((mod & MOD_SL) != 0) {
318 mod -= MOD_SL;
319 // Propagate lower bound for positive Boolean views
320 {
321 ScaleBool* f=p.fst();
322 for (ScaleBool* l=p.lst(); (f < l) && (f->a > sl_p); f++) {
323 GECODE_ME_CHECK(f->x.zero_none(home));
324 su_n -= f->a;
325 }
326 if (f > p.fst()) {
327 p.fst(f); mod |= MOD_SU;
328 }
329 }
330 // Propagate lower bound for negative Boolean views
331 {
332 ScaleBool* f=n.fst();
333 for (ScaleBool* l=n.lst(); (f < l) && (f->a > sl_p); f++) {
334 GECODE_ME_CHECK(f->x.one_none(home)); c += f->a;
335 su_n -= f->a;
336 }
337 if (f > n.fst()) {
338 n.fst(f); mod |= MOD_SU;
339 }
340 }
341 // Propagate lower bound for integer view
342 {
343 const int x_min = x.min();
344 ModEvent me = x.gq(home,x.max() - sl_p);
345 if (me_failed(me))
346 return ES_FAILED;
347 if (me_modified(me)) {
348 su_n -= x.min() - x_min;
349 mod |= MOD_SU;
350 }
351 }
352 }
353 if ((mod & MOD_SU) != 0) {
354 mod -= MOD_SU;
355 // Propagate upper bound for positive Boolean views
356 {
357 ScaleBool* f=p.fst();
358 for (ScaleBool* l=p.lst(); (f < l) && (f->a > su_n); f++) {
359 GECODE_ME_CHECK(f->x.one_none(home)); c -= f->a;
360 sl_p -= f->a;
361 }
362 if (f > p.fst()) {
363 p.fst(f); mod |= MOD_SL;;
364 }
365 }
366 // Propagate upper bound for negative Boolean views
367 {
368 ScaleBool* f=n.fst();
369 for (ScaleBool* l=n.lst(); (f < l) && (f->a > su_n); f++) {
370 GECODE_ME_CHECK(f->x.zero_none(home));
371 sl_p -= f->a;
372 }
373 if (f > n.fst()) {
374 n.fst(f); mod |= MOD_SL;;
375 }
376 }
377 // Propagate upper bound for integer view
378 {
379 const int x_max = x.max();
380 ModEvent me = x.lq(home,x.min() + su_n);
381 if (me_failed(me))
382 return ES_FAILED;
383 if (me_modified(me)) {
384 sl_p += x.max() - x_max;
385 mod |= MOD_SL;;
386 }
387 }
388 }
389 } while (mod != 0);
390
391 return (sl_p == -su_n) ? home.ES_SUBSUMED(*this) : ES_FIX;
392 }
393
394
395
396 template<class SBAP, class SBAN, class VX>
397 ExecStatus
398 EqBoolScale<SBAP,SBAN,VX>::post(Home home,
399 SBAP& p, SBAN& n, VX x, int c) {
400 p.sort(); n.sort();
401 if (p.empty()) {
402 EmptyScaleBoolArray ep;
403 (void) new (home) EqBoolScale<EmptyScaleBoolArray,SBAN,VX>
404 (home,ep,n,x,c);
405 } else if (n.empty()) {
406 EmptyScaleBoolArray en;
407 (void) new (home) EqBoolScale<SBAP,EmptyScaleBoolArray,VX>
408 (home,p,en,x,c);
409 } else {
410 (void) new (home) EqBoolScale<SBAP,SBAN,VX>
411 (home,p,n,x,c);
412 }
413 return ES_OK;
414 }
415
416
417 /*
418 * Boolean inequality with coefficients
419 *
420 */
421
422 template<class SBAP, class SBAN, class VX>
423 forceinline
424 LqBoolScale<SBAP,SBAN,VX>::LqBoolScale(Home home,
425 SBAP& p, SBAN& n,
426 VX x, int c)
427 : LinBoolScale<SBAP,SBAN,VX,PC_INT_BND>(home,p,n,x,c) {}
428
429 template<class SBAP, class SBAN, class VX>
430 forceinline
431 LqBoolScale<SBAP,SBAN,VX>::LqBoolScale(Space& home,
432 Propagator& pr,
433 SBAP& p, SBAN& n,
434 VX x, int c)
435 : LinBoolScale<SBAP,SBAN,VX,PC_INT_BND>(home,pr,p,n,x,c) {}
436
437 template<class SBAP, class SBAN, class VX>
438 Actor*
439 LqBoolScale<SBAP,SBAN,VX>::copy(Space& home) {
440 if (p.empty()) {
441 EmptyScaleBoolArray ep;
442 if (x.assigned()) {
443 ZeroIntView z;
444 return new (home) LqBoolScale<EmptyScaleBoolArray,SBAN,ZeroIntView>
445 (home,*this,ep,n,z,c+x.val());
446 } else {
447 return new (home) LqBoolScale<EmptyScaleBoolArray,SBAN,VX>
448 (home,*this,ep,n,x,c);
449 }
450 } else if (n.empty()) {
451 EmptyScaleBoolArray en;
452 if (x.assigned()) {
453 ZeroIntView z;
454 return new (home) LqBoolScale<SBAP,EmptyScaleBoolArray,ZeroIntView>
455 (home,*this,p,en,z,c+x.val());
456 } else {
457 return new (home) LqBoolScale<SBAP,EmptyScaleBoolArray,VX>
458 (home,*this,p,en,x,c);
459 }
460 } else {
461 return new (home) LqBoolScale<SBAP,SBAN,VX>(home,*this,p,n,x,c);
462 }
463 }
464
465 template<class SBAP, class SBAN, class VX>
466 ExecStatus
467 LqBoolScale<SBAP,SBAN,VX>::propagate(Space& home, const ModEventDelta& med) {
468 int sl = 0;
469 if (BoolView::me(med) == ME_BOOL_VAL) {
470 // Eliminate assigned positive views while keeping order
471 {
472 // Skip not assigned views
473 ScaleBool* f = p.fst();
474 ScaleBool* l = p.lst();
475 while ((f < l) && f->x.none())
476 f++;
477 // Copy unassigned views to t
478 ScaleBool* t = f;
479 while (f < l) {
480 if (f->x.one()) {
481 c -= f->a;
482 } else if (f->x.none()) {
483 *t = *f; t++;
484 }
485 f++;
486 }
487 p.lst(t);
488 }
489 // Eliminate assigned negative views while keeping order
490 {
491 // Skip not assigned views
492 ScaleBool* f = n.fst();
493 ScaleBool* l = n.lst();
494 while ((f < l) && f->x.none()) {
495 sl += f->a; f++;
496 }
497 // Copy unassigned views to t
498 ScaleBool* t = f;
499 while (f < l) {
500 if (f->x.one()) {
501 c += f->a;
502 } else if (f->x.none()) {
503 sl += f->a; *t = *f; t++;
504 }
505 f++;
506 }
507 n.lst(t);
508 }
509 } else {
510 for (ScaleBool* f=n.fst(); f<n.lst(); f++)
511 sl += f->a;
512 }
513
514 sl += x.max() + c;
515
516 // Propagate upper bound for positive Boolean views
517 {
518 ScaleBool* f=p.fst();
519 for (ScaleBool* l=p.lst(); (f < l) && (f->a > sl); f++)
520 GECODE_ME_CHECK(f->x.zero_none(home));
521 p.fst(f);
522 }
523 // Propagate lower bound for negative Boolean views
524 {
525 ScaleBool* f=n.fst();
526 for (ScaleBool* l=n.lst(); (f < l) && (f->a > sl); f++) {
527 c += f->a;
528 GECODE_ME_CHECK(f->x.one_none(home));
529 }
530 n.fst(f);
531 }
532 ExecStatus es = ES_FIX;
533 // Propagate lower bound for integer view
534 {
535 const int slx = x.max() - sl;
536 ModEvent me = x.gq(home,slx);
537 if (me_failed(me))
538 return ES_FAILED;
539 if (me_modified(me) && (slx != x.min()))
540 es = ES_NOFIX;
541 }
542
543 if (p.empty() && n.empty())
544 return home.ES_SUBSUMED(*this);
545
546 return es;
547 }
548
549
550
551 template<class SBAP, class SBAN, class VX>
552 ExecStatus
553 LqBoolScale<SBAP,SBAN,VX>::post(Home home,
554 SBAP& p, SBAN& n, VX x, int c) {
555 p.sort(); n.sort();
556 if (p.empty()) {
557 EmptyScaleBoolArray ep;
558 (void) new (home) LqBoolScale<EmptyScaleBoolArray,SBAN,VX>
559 (home,ep,n,x,c);
560 } else if (n.empty()) {
561 EmptyScaleBoolArray en;
562 (void) new (home) LqBoolScale<SBAP,EmptyScaleBoolArray,VX>
563 (home,p,en,x,c);
564 } else {
565 (void) new (home) LqBoolScale<SBAP,SBAN,VX>
566 (home,p,n,x,c);
567 }
568 return ES_OK;
569 }
570
571 /*
572 * Boolean disequality with coefficients
573 *
574 */
575
576 template<class SBAP, class SBAN, class VX>
577 forceinline
578 NqBoolScale<SBAP,SBAN,VX>::NqBoolScale(Home home,
579 SBAP& p, SBAN& n,
580 VX x, int c)
581 : LinBoolScale<SBAP,SBAN,VX,PC_INT_VAL>(home,p,n,x,c) {}
582
583 template<class SBAP, class SBAN, class VX>
584 forceinline
585 NqBoolScale<SBAP,SBAN,VX>::NqBoolScale(Space& home,
586 Propagator& pr,
587 SBAP& p, SBAN& n,
588 VX x, int c)
589 : LinBoolScale<SBAP,SBAN,VX,PC_INT_VAL>(home,pr,p,n,x,c) {}
590
591 template<class SBAP, class SBAN, class VX>
592 Actor*
593 NqBoolScale<SBAP,SBAN,VX>::copy(Space& home) {
594 if (p.empty()) {
595 EmptyScaleBoolArray ep;
596 if (x.assigned()) {
597 ZeroIntView z;
598 return new (home) NqBoolScale<EmptyScaleBoolArray,SBAN,ZeroIntView>
599 (home,*this,ep,n,z,c+x.val());
600 } else {
601 return new (home) NqBoolScale<EmptyScaleBoolArray,SBAN,VX>
602 (home,*this,ep,n,x,c);
603 }
604 } else if (n.empty()) {
605 EmptyScaleBoolArray en;
606 if (x.assigned()) {
607 ZeroIntView z;
608 return new (home) NqBoolScale<SBAP,EmptyScaleBoolArray,ZeroIntView>
609 (home,*this,p,en,z,c+x.val());
610 } else {
611 return new (home) NqBoolScale<SBAP,EmptyScaleBoolArray,VX>
612 (home,*this,p,en,x,c);
613 }
614 } else {
615 return new (home) NqBoolScale<SBAP,SBAN,VX>(home,*this,p,n,x,c);
616 }
617 }
618
619 template<class SBAP, class SBAN, class VX>
620 ExecStatus
621 NqBoolScale<SBAP,SBAN,VX>::propagate(Space& home, const ModEventDelta& med) {
622 if (BoolView::me(med) == ME_BOOL_VAL) {
623 // Eliminate assigned positive views
624 {
625 ScaleBool* f = p.fst();
626 ScaleBool* t = f;
627 ScaleBool* l = p.lst();
628 while (f < l) {
629 if (f->x.one()) {
630 c -= f->a; *f = *(t++);
631 } else if (f->x.zero()) {
632 *f = *(t++);
633 }
634 f++;
635 }
636 p.fst(t);
637 }
638 // Eliminate assigned negative views
639 {
640 ScaleBool* f = n.fst();
641 ScaleBool* t = f;
642 ScaleBool* l = n.lst();
643 while (f < l) {
644 if (f->x.one()) {
645 c += f->a; *f = *(t++);
646 } else if (f->x.zero()) {
647 *f = *(t++);
648 }
649 f++;
650 }
651 n.fst(t);
652 }
653 }
654
655 if (p.empty() && n.empty()) {
656 GECODE_ME_CHECK(x.nq(home,-c));
657 return home.ES_SUBSUMED(*this);
658 }
659
660 if (x.assigned()) {
661 int r = x.val()+c;
662 if (p.empty() && (n.size() == 1)) {
663 if (r == -n.fst()->a) {
664 GECODE_ME_CHECK(n.fst()->x.zero_none(home));
665 } else if (r == 0) {
666 GECODE_ME_CHECK(n.fst()->x.one_none(home));
667 }
668 return home.ES_SUBSUMED(*this);
669 }
670 if ((p.size() == 1) && n.empty()) {
671 if (r == p.fst()->a) {
672 GECODE_ME_CHECK(p.fst()->x.zero_none(home));
673 } else if (r == 0) {
674 GECODE_ME_CHECK(p.fst()->x.one_none(home));
675 }
676 return home.ES_SUBSUMED(*this);
677 }
678 }
679 return ES_FIX;
680 }
681
682
683
684 template<class SBAP, class SBAN, class VX>
685 ExecStatus
686 NqBoolScale<SBAP,SBAN,VX>::post(Home home,
687 SBAP& p, SBAN& n, VX x, int c) {
688 if (p.empty()) {
689 EmptyScaleBoolArray ep;
690 (void) new (home) NqBoolScale<EmptyScaleBoolArray,SBAN,VX>
691 (home,ep,n,x,c);
692 } else if (n.empty()) {
693 EmptyScaleBoolArray en;
694 (void) new (home) NqBoolScale<SBAP,EmptyScaleBoolArray,VX>
695 (home,p,en,x,c);
696 } else {
697 (void) new (home) NqBoolScale<SBAP,SBAN,VX>
698 (home,p,n,x,c);
699 }
700 return ES_OK;
701 }
702
703}}}
704
705// STATISTICS: int-prop
706