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 36namespace Gecode { namespace Int { namespace Member { 37 38 template<class View, ReifyMode rm> 39 forceinline 40 ReProp<View,rm>::ReProp(Home home, ValSet& vs, ViewArray<View>& x, View y, 41 BoolView b0) 42 : Prop<View>(home,vs,x,y), b(b0) { 43 b.subscribe(home,*this,PC_BOOL_VAL); 44 } 45 46 template<class View, ReifyMode rm> 47 inline ExecStatus 48 ReProp<View,rm>::post(Home home, ViewArray<View>& x, View y, BoolView b) { 49 if (x.size() == 0) { 50 if (rm != RM_PMI) 51 GECODE_ME_CHECK(b.zero(home)); 52 return ES_OK; 53 } 54 55 x.unique(); 56 57 if (x.size() == 1) 58 return Rel::ReEqDom<View,BoolView,rm>::post(home,x[0],y,b); 59 60 if (x.same(y)) { 61 if (rm != RM_IMP) 62 GECODE_ME_CHECK(b.one(home)); 63 return ES_OK; 64 } 65 66 // Eliminate assigned views and store them into the value set 67 ValSet vs; 68 add(home, vs, x); 69 70 switch (vs.compare(y)) { 71 case Iter::Ranges::CS_SUBSET: 72 if (rm != RM_IMP) 73 GECODE_ME_CHECK(b.one(home)); 74 return ES_OK; 75 case Iter::Ranges::CS_DISJOINT: 76 if (x.size() == 0) { 77 if (rm != RM_PMI) 78 GECODE_ME_CHECK(b.zero(home)); 79 return ES_OK; 80 } 81 break; 82 case Iter::Ranges::CS_NONE: 83 break; 84 default: 85 GECODE_NEVER; 86 } 87 88 (void) new (home) ReProp<View,rm>(home, vs, x, y, b); 89 return ES_OK; 90 } 91 92 template<class View, ReifyMode rm> 93 forceinline 94 ReProp<View,rm>::ReProp(Space& home, ReProp<View,rm>& p) 95 : Prop<View>(home, p) { 96 b.update(home, p.b); 97 } 98 99 template<class View, ReifyMode rm> 100 Propagator* 101 ReProp<View,rm>::copy(Space& home) { 102 return new (home) ReProp<View,rm>(home, *this); 103 } 104 105 template<class View, ReifyMode rm> 106 forceinline size_t 107 ReProp<View,rm>::dispose(Space& home) { 108 b.cancel(home, *this, PC_BOOL_VAL); 109 (void) Prop<View>::dispose(home); 110 return sizeof(*this); 111 } 112 113 template<class View, ReifyMode rm> 114 ExecStatus 115 ReProp<View,rm>::propagate(Space& home, const ModEventDelta& med) { 116 // Add assigned views to value set 117 if (View::me(med) == ME_INT_VAL) 118 add(home,vs,x); 119 120 if (b.one()) { 121 if (rm == RM_PMI) 122 return home.ES_SUBSUMED(*this); 123 ValSet vsc(vs); 124 vs.flush(); 125 GECODE_REWRITE(*this,Prop<View>::post(home(*this),vsc,x,y)); 126 } 127 128 if (b.zero()) { 129 if (rm != RM_IMP) { 130 ValSet::Ranges vsr(vs); 131 GECODE_ME_CHECK(y.minus_r(home,vsr,false)); 132 for (int i=0; i<x.size(); i++) 133 GECODE_ES_CHECK((Rel::Nq<View,View>::post(Home(home),x[i],y))); 134 } 135 return home.ES_SUBSUMED(*this); 136 } 137 138 // Eliminate views from x 139 eliminate(home); 140 141 switch (vs.compare(y)) { 142 case Iter::Ranges::CS_SUBSET: 143 if (rm != RM_IMP) 144 GECODE_ME_CHECK(b.one(home)); 145 return home.ES_SUBSUMED(*this); 146 case Iter::Ranges::CS_DISJOINT: 147 if (x.size() == 0) { 148 if (rm != RM_PMI) 149 GECODE_ME_CHECK(b.zero(home)); 150 return home.ES_SUBSUMED(*this); 151 } 152 break; 153 case Iter::Ranges::CS_NONE: 154 break; 155 default: 156 GECODE_NEVER; 157 } 158 159 // Check whether y is in union of x and value set 160 if (x.size() > 0) { 161 Region r; 162 163 ValSet::Ranges vsr(vs); 164 ViewRanges<View> xsr(x[0]); 165 Iter::Ranges::NaryUnion u(r,vsr,xsr); 166 for (int i=1; i<x.size(); i++) { 167 ViewRanges<View> xir(x[i]); 168 u |= xir; 169 } 170 171 ViewRanges<View> yr(y); 172 173 if (Iter::Ranges::disjoint(u,yr)) { 174 if (rm != RM_PMI) 175 GECODE_ME_CHECK(b.zero(home)); 176 return home.ES_SUBSUMED(*this); 177 } 178 } 179 180 return ES_FIX; 181 } 182 183}}} 184 185// STATISTICS: int-prop