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 * Guido Tack <tack@gecode.org> 6 * 7 * Copyright: 8 * Christian Schulte, 2009 9 * Guido Tack, 2010 10 * 11 * This file is part of Gecode, the generic constraint 12 * development environment: 13 * http://www.gecode.org 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining 16 * a copy of this software and associated documentation files (the 17 * "Software"), to deal in the Software without restriction, including 18 * without limitation the rights to use, copy, modify, merge, publish, 19 * distribute, sublicense, and/or sell copies of the Software, and to 20 * permit persons to whom the Software is furnished to do so, subject to 21 * the following conditions: 22 * 23 * The above copyright notice and this permission notice shall be 24 * included in all copies or substantial portions of the Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 * 34 */ 35 36#include <gecode/int/unary.hh> 37#include <gecode/int/distinct.hh> 38 39#include <algorithm> 40 41namespace Gecode { 42 43 void 44 unary(Home home, const IntVarArgs& s, const IntArgs& p, IntPropLevel ipl) { 45 using namespace Gecode::Int; 46 using namespace Gecode::Int::Unary; 47 if (same(s)) 48 throw Int::ArgumentSame("Int::unary"); 49 if (s.size() != p.size()) 50 throw Int::ArgumentSizeMismatch("Int::unary"); 51 for (int i=0; i<p.size(); i++) { 52 Int::Limits::nonnegative(p[i],"Int::unary"); 53 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i], 54 "Int::unary"); 55 } 56 GECODE_POST; 57 bool allOne = true; 58 for (int i=0; i<p.size(); i++) { 59 if (p[i] != 1) { 60 allOne = false; 61 break; 62 } 63 } 64 if (allOne) { 65 ViewArray<IntView> xv(home,s); 66 switch (vbd(ipl)) { 67 case IPL_BND: 68 GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv)); 69 break; 70 case IPL_DOM: 71 GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); 72 break; 73 default: 74 GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv)); 75 } 76 } else { 77 TaskArray<ManFixPTask> t(home,s.size()); 78 for (int i=0; i<s.size(); i++) 79 t[i].init(s[i],p[i]); 80 GECODE_ES_FAIL(manpost(home,t,ipl)); 81 } 82 } 83 84 void 85 unary(Home home, const TaskTypeArgs& t, 86 const IntVarArgs& flex, const IntArgs& fix, IntPropLevel ipl) { 87 using namespace Gecode::Int; 88 using namespace Gecode::Int::Unary; 89 if ((flex.size() != fix.size()) || (flex.size() != t.size())) 90 throw Int::ArgumentSizeMismatch("Int::unary"); 91 for (int i=0; i<fix.size(); i++) { 92 if (t[i] == TT_FIXP) 93 Int::Limits::nonnegative(fix[i],"Int::unary"); 94 else 95 Int::Limits::check(fix[i],"Int::unary"); 96 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i], 97 "Int::unary"); 98 } 99 GECODE_POST; 100 bool fixp = true; 101 for (int i=0; i<t.size(); i++) 102 if (t[i] != TT_FIXP) { 103 fixp = false; break; 104 } 105 if (fixp) { 106 unary(home, flex, fix, ipl); 107 } else { 108 TaskArray<ManFixPSETask> tasks(home,flex.size()); 109 for (int i=0; i<flex.size(); i++) 110 tasks[i].init(t[i],flex[i],fix[i]); 111 GECODE_ES_FAIL(manpost(home,tasks,ipl)); 112 } 113 } 114 115 void 116 unary(Home home, const IntVarArgs& s, const IntArgs& p, 117 const BoolVarArgs& m, IntPropLevel ipl) { 118 using namespace Gecode::Int; 119 using namespace Gecode::Int::Unary; 120 if (same(s)) 121 throw Int::ArgumentSame("Int::unary"); 122 if ((s.size() != p.size()) || (s.size() != m.size())) 123 throw Int::ArgumentSizeMismatch("Int::unary"); 124 for (int i=0; i<p.size(); i++) { 125 Int::Limits::nonnegative(p[i],"Int::unary"); 126 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i], 127 "Int::unary"); 128 } 129 bool allMandatory = true; 130 for (int i=0; i<m.size(); i++) { 131 if (!m[i].one()) { 132 allMandatory = false; 133 break; 134 } 135 } 136 if (allMandatory) { 137 unary(home,s,p,ipl); 138 } else { 139 GECODE_POST; 140 TaskArray<OptFixPTask> t(home,s.size()); 141 for (int i=0; i<s.size(); i++) 142 t[i].init(s[i],p[i],m[i]); 143 GECODE_ES_FAIL(optpost(home,t,ipl)); 144 } 145 } 146 147 void 148 unary(Home home, const TaskTypeArgs& t, 149 const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m, 150 IntPropLevel ipl) { 151 using namespace Gecode::Int; 152 using namespace Gecode::Int::Unary; 153 if ((flex.size() != fix.size()) || (flex.size() != t.size()) || 154 (flex.size() != m.size())) 155 throw Int::ArgumentSizeMismatch("Int::unary"); 156 bool fixp = true; 157 for (int i=0; i<fix.size(); i++) { 158 if (t[i] == TT_FIXP) { 159 Int::Limits::nonnegative(fix[i],"Int::unary"); 160 } else { 161 fixp = false; 162 Int::Limits::check(fix[i],"Int::unary"); 163 } 164 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i], 165 "Int::unary"); 166 } 167 GECODE_POST; 168 bool allMandatory = true; 169 for (int i=0; i<m.size(); i++) { 170 if (!m[i].one()) { 171 allMandatory = false; 172 break; 173 } 174 } 175 if (allMandatory) { 176 unary(home,t,flex,fix,ipl); 177 } else { 178 if (fixp) { 179 TaskArray<OptFixPTask> tasks(home,flex.size()); 180 for (int i=0; i<flex.size(); i++) 181 tasks[i].init(flex[i],fix[i],m[i]); 182 GECODE_ES_FAIL(optpost(home,tasks,ipl)); 183 } else { 184 TaskArray<OptFixPSETask> tasks(home,flex.size()); 185 for (int i=0; i<flex.size(); i++) 186 tasks[i].init(t[i],flex[i],fix[i],m[i]); 187 GECODE_ES_FAIL(optpost(home,tasks,ipl)); 188 } 189 } 190 } 191 192 void 193 unary(Home home, const IntVarArgs& s, const IntVarArgs& p, 194 const IntVarArgs& e, IntPropLevel ipl) { 195 using namespace Gecode::Int; 196 using namespace Gecode::Int::Unary; 197 if ((s.size() != p.size()) || (s.size() != e.size())) 198 throw Int::ArgumentSizeMismatch("Int::unary"); 199 GECODE_POST; 200 for (int i=0; i<p.size(); i++) { 201 IntView pi(p[i]); 202 GECODE_ME_FAIL(pi.gq(home,0)); 203 } 204 bool fixP = true; 205 for (int i=0; i<p.size(); i++) { 206 if (!p[i].assigned()) { 207 fixP = false; 208 break; 209 } 210 } 211 if (fixP) { 212 IntArgs pp(p.size()); 213 for (int i=0; i<p.size(); i++) 214 pp[i] = p[i].val(); 215 unary(home,s,pp,ipl); 216 } else { 217 TaskArray<ManFlexTask> t(home,s.size()); 218 for (int i=0; i<s.size(); i++) 219 t[i].init(s[i],p[i],e[i]); 220 GECODE_ES_FAIL(manpost(home,t,ipl)); 221 } 222 } 223 224 void 225 unary(Home home, const IntVarArgs& s, const IntVarArgs& p, 226 const IntVarArgs& e, const BoolVarArgs& m, IntPropLevel ipl) { 227 using namespace Gecode::Int; 228 using namespace Gecode::Int::Unary; 229 if ((s.size() != p.size()) || (s.size() != m.size()) || 230 (s.size() != e.size())) 231 throw Int::ArgumentSizeMismatch("Int::unary"); 232 GECODE_POST; 233 for (int i=0; i<p.size(); i++) { 234 IntView pi(p[i]); 235 GECODE_ME_FAIL(pi.gq(home,0)); 236 } 237 bool allMandatory = true; 238 for (int i=0; i<m.size(); i++) { 239 if (!m[i].one()) { 240 allMandatory = false; 241 break; 242 } 243 } 244 if (allMandatory) { 245 unary(home,s,p,e,ipl); 246 } else { 247 TaskArray<OptFlexTask> t(home,s.size()); 248 for (int i=0; i<s.size(); i++) 249 t[i].init(s[i],p[i],e[i],m[i]); 250 GECODE_ES_FAIL(optpost(home,t,ipl)); 251 } 252 } 253 254} 255 256// STATISTICS: int-post