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 EqInt<VY>::EqInt(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 EqInt<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 if (x.size() == 1) { 57 GECODE_ME_CHECK(y.eq(home,1)); 58 return ES_OK; 59 } 60 61 GECODE_ME_CHECK(y.gq(home,1)); 62 GECODE_ME_CHECK(y.lq(home,x.size())); 63 64 if (y.max() == 1) { 65 assert(y.assigned()); 66 return Rel::NaryEqDom<IntView>::post(home,x); 67 } 68 69 if (y.min() == x.size()) { 70 assert(y.assigned()); 71 return Distinct::Dom<IntView>::post(home,x); 72 } 73 74 // Eliminate assigned views and store them into the value set 75 ValSet vs; 76 int n = x.size(); 77 for (int i=n; i--; ) 78 if (x[i].assigned()) { 79 vs.add(home, x[i].val()); 80 x[i] = x[--n]; 81 } 82 83 GECODE_ME_CHECK(y.gq(home,vs.size())); 84 GECODE_ME_CHECK(y.lq(home,n + vs.size())); 85 86 if (n == 0) { 87 assert(y.val() == vs.size()); 88 return ES_OK; 89 } 90 x.size(n); 91 (void) new (home) EqInt<VY>(home, vs, x, y); 92 return ES_OK; 93 } 94 95 template<class VY> 96 forceinline 97 EqInt<VY>::EqInt(Space& home, EqInt<VY>& p) 98 : IntBase<VY>(home, p) {} 99 100 template<class VY> 101 Propagator* 102 EqInt<VY>::copy(Space& home) { 103 return new (home) EqInt<VY>(home, *this); 104 } 105 106 template<class VY> 107 forceinline size_t 108 EqInt<VY>::dispose(Space& home) { 109 home.ignore(*this, AP_WEAKLY); 110 (void) IntBase<VY>::dispose(home); 111 return sizeof(*this); 112 } 113 114 template<class VY> 115 ExecStatus 116 EqInt<VY>::propagate(Space& home, const ModEventDelta& med) { 117 // Add assigned views to value set 118 if (IntView::me(med) == ME_INT_VAL) 119 add(home); 120 121 GECODE_ME_CHECK(y.gq(home, vs.size())); 122 GECODE_ME_CHECK(y.lq(home, x.size() + vs.size())); 123 124 if (x.size() == 0) 125 return home.ES_SUBSUMED(*this); 126 127 // All values must be in the value set 128 if (y.max() == vs.size()) 129 return all_in_valset(home); 130 131 // Compute positions of disjoint views and eliminate subsumed views 132 Region r; 133 int* dis; int n_dis; 134 disjoint(home,r,dis,n_dis); 135 136 // The number might have changed due to elimination of subsumed views 137 GECODE_ME_CHECK(y.lq(home, x.size() + vs.size())); 138 139 if (x.size() == 0) { 140 assert(y.val() == vs.size()); 141 return home.ES_SUBSUMED(*this); 142 } 143 144 GECODE_ES_CHECK(prune_upper(home,g)); 145 146 // No lower bound pruning possible 147 if (n_dis == 0) 148 return ES_NOFIX; 149 150 // Only if the propagator is at fixpoint here, continue with 151 // propagating the lower bound 152 if (IntView::me(Propagator::modeventdelta()) != ME_INT_NONE) 153 return ES_NOFIX; 154 155 // Do lower bound-based pruning 156 GECODE_ES_CHECK(prune_lower(home,dis,n_dis)); 157 158 return ES_NOFIX; 159 } 160 161}}} 162 163// STATISTICS: int-prop