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, 2011 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 34#include <gecode/int/rel.hh> 35#include <gecode/int/distinct.hh> 36 37namespace Gecode { namespace Int { namespace NValues { 38 39 template<class VY> 40 forceinline 41 LqInt<VY>::LqInt(Home home, ValSet& vs, ViewArray<IntView>& x, VY y) 42 : IntBase<VY>(home,vs,x,y) { 43 home.notice(*this, AP_WEAKLY); 44 } 45 46 template<class VY> 47 inline ExecStatus 48 LqInt<VY>::post(Home home, ViewArray<IntView>& x, VY y) { 49 if (x.size() == 0) { 50 GECODE_ME_CHECK(y.eq(home,0)); 51 return ES_OK; 52 } 53 54 x.unique(); 55 56 GECODE_ME_CHECK(y.gq(home,1)); 57 58 if (x.size() == 1) 59 return ES_OK; 60 61 if (y.max() == 1) { 62 assert(y.assigned()); 63 return Rel::NaryEqDom<IntView>::post(home,x); 64 } 65 66 if (y.min() >= x.size()) 67 return ES_OK; 68 69 // Eliminate assigned views and store them into the value set 70 ValSet vs; 71 int n = x.size(); 72 for (int i=n; i--; ) 73 if (x[i].assigned()) { 74 vs.add(home, x[i].val()); 75 x[i] = x[--n]; 76 } 77 78 GECODE_ME_CHECK(y.gq(home,vs.size())); 79 80 if (n == 0) { 81 assert(y.min() >= vs.size()); 82 return ES_OK; 83 } 84 85 x.size(n); 86 87 (void) new (home) LqInt<VY>(home, vs, x, y); 88 return ES_OK; 89 } 90 91 template<class VY> 92 forceinline 93 LqInt<VY>::LqInt(Space& home, LqInt<VY>& p) 94 : IntBase<VY>(home, p) {} 95 96 template<class VY> 97 Propagator* 98 LqInt<VY>::copy(Space& home) { 99 return new (home) LqInt<VY>(home, *this); 100 } 101 102 template<class VY> 103 forceinline size_t 104 LqInt<VY>::dispose(Space& home) { 105 home.ignore(*this, AP_WEAKLY); 106 (void) IntBase<VY>::dispose(home); 107 return sizeof(*this); 108 } 109 110 template<class VY> 111 ExecStatus 112 LqInt<VY>::propagate(Space& home, const ModEventDelta& med) { 113 // Add assigned views to value set 114 if (IntView::me(med) == ME_INT_VAL) 115 add(home); 116 117 GECODE_ME_CHECK(y.gq(home, vs.size())); 118 119 if (x.size() == 0) 120 return home.ES_SUBSUMED(*this); 121 122 // All values must be in the value set 123 if (y.max() == vs.size()) 124 return all_in_valset(home); 125 126 if (x.size() + vs.size() <= y.min()) 127 return home.ES_SUBSUMED(*this); 128 129 // Compute positions of disjoint views 130 Region r; 131 int* dis; int n_dis; 132 disjoint(home,r,dis,n_dis); 133 134 // Some views might have been eliminated as they are subsumed 135 if (x.size() == 0) 136 return home.ES_SUBSUMED(*this); 137 138 // No lower bound pruning possible 139 if (n_dis == 0) 140 return ES_NOFIX; 141 142 // Do lower bound-based pruning 143 GECODE_ES_CHECK(prune_lower(home,dis,n_dis)); 144 145 return ES_NOFIX; 146 } 147 148}}} 149 150// STATISTICS: int-prop