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