this repo has no description
at develop 92 kB view raw
1/* 2 * Main authors: 3 * Kevin Leo <kevin.leo@monash.edu> 4 * Andrea Rendl <andrea.rendl@nicta.com.au> 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#include <minizinc/ast.hh> 13#include <minizinc/eval_par.hh> 14#include <minizinc/exception.hh> 15#include <minizinc/solvers/gecode/fzn_space.hh> 16#include <minizinc/solvers/gecode/gecode_constraints.hh> 17#include <minizinc/solvers/gecode_solverinstance.hh> 18 19#include "aux_brancher.hh" 20 21#include <utility> 22 23using namespace std; 24using namespace Gecode; 25 26namespace MiniZinc { 27 28GecodeSolverFactory::GecodeSolverFactory() { 29 SolverConfig sc("org.minizinc.gecode_presolver", GECODE_VERSION); 30 sc.name("Presolver"); 31 sc.mznlib("-Ggecode_presolver"); 32 sc.mznlibVersion(1); 33 sc.supportsMzn(false); 34 sc.description("Internal Gecode presolver plugin"); 35 sc.tags({"cp", "float", "api", "set", "gecode_presolver", "__internal__"}); 36 sc.stdFlags({"-a", "-n"}); 37 SolverConfigs::registerBuiltinSolver(sc); 38} 39 40SolverInstanceBase::Options* GecodeSolverFactory::createOptions() { return new GecodeOptions; } 41 42SolverInstanceBase* GecodeSolverFactory::doCreateSI(Env& env, std::ostream& log, 43 SolverInstanceBase::Options* opt) { 44 return new GecodeSolverInstance(env, log, opt); 45} 46 47string GecodeSolverFactory::getDescription(SolverInstanceBase::Options* /*opt*/) { 48 string v = "Gecode solver plugin, compiled " __DATE__ ", using: Gecode version " + 49 string(GECODE_VERSION); 50 return v; 51} 52 53string GecodeSolverFactory::getVersion(SolverInstanceBase::Options* /*opt*/) { 54 return string(GECODE_VERSION); 55} 56 57bool GecodeSolverFactory::processOption(SolverInstanceBase::Options* opt, int& i, 58 std::vector<std::string>& argv, 59 const std::string& workingDir) { 60 auto& _opt = static_cast<GecodeOptions&>(*opt); 61 if (string(argv[i]) == "--allow-unbounded-vars") { 62 _opt.allowUnboundedVars = true; 63 } else if (string(argv[i]) == "--only-range-domains") { 64 _opt.onlyRangeDomains = true; 65 } else if (string(argv[i]) == "--sac") { 66 _opt.sac = true; 67 } else if (string(argv[i]) == "--shave") { 68 _opt.shave = true; 69 } else if (string(argv[i]) == "--pre-passes") { 70 if (++i == argv.size()) { 71 return false; 72 } 73 int passes = atoi(argv[i].c_str()); 74 if (passes >= 0) { 75 _opt.prePasses = passes; 76 } 77 } else if (string(argv[i]) == "-a" || string(argv[i]) == "--all-solutions") { 78 _opt.allSolutions = true; 79 } else if (string(argv[i]) == "-n") { 80 if (++i == argv.size()) { 81 return false; 82 } 83 int n = atoi(argv[i].c_str()); 84 if (n >= 0) { 85 _opt.nSolutions = n; 86 } 87 } else if (string(argv[i]) == "--node") { 88 if (++i == argv.size()) { 89 return false; 90 } 91 int nodes = atoi(argv[i].c_str()); 92 if (nodes >= 0) { 93 _opt.nodes = nodes; 94 } 95 } else if (string(argv[i]) == "--c_d") { 96 if (++i == argv.size()) { 97 return false; 98 } 99 int c_d = atoi(argv[i].c_str()); 100 if (c_d >= 0) { 101 _opt.c_d = static_cast<unsigned int>(c_d); 102 } 103 } else if (string(argv[i]) == "--a_d") { 104 if (++i == argv.size()) { 105 return false; 106 } 107 int a_d = atoi(argv[i].c_str()); 108 if (a_d >= 0) { 109 _opt.a_d = static_cast<unsigned int>(a_d); 110 } 111 } else if (string(argv[i]) == "--fail") { 112 if (++i == argv.size()) { 113 return false; 114 } 115 int fails = atoi(argv[i].c_str()); 116 if (fails >= 0) { 117 _opt.fails = fails; 118 } 119 } else if (argv[i] == "--solver-time-limit" || argv[i] == "-t") { 120 if (++i == argv.size()) { 121 return false; 122 } 123 int time = atoi(argv[i].c_str()); 124 if (time >= 0) { 125 _opt.time = time; 126 } 127 } else if (string(argv[i]) == "-v" || string(argv[i]) == "--verbose-solving") { 128 _opt.verbose = true; 129 } else if (string(argv[i]) == "-s" || string(argv[i]) == "--solver-statistics") { 130 _opt.statistics = true; 131 } else { 132 return false; 133 } 134 return true; 135} 136 137void GecodeSolverFactory::printHelp(ostream& os) { 138 os << "Gecode solver plugin options:" << std::endl 139 << " --allow-unbounded-vars" << std::endl 140 << " give unbounded variables maximum bounds (this may lead to incorrect behaviour)" 141 << std::endl 142 << " --only-range-domains" << std::endl 143 << " only tighten bounds" << std::endl 144 << " --sac" << std ::endl 145 << " singleton arc consistency" << std::endl 146 << " --shave" << std::endl 147 << " shave domains" << std::endl 148 << " --pre-passes <n>" << std::endl 149 << " n passes of sac/shaving, 0 for fixed point" << std::endl 150 << " --c_d <n>" << std::endl 151 << " recomputation commit distance" << std::endl 152 << " --a_d <n>" << std::endl 153 << " recomputation adaption distance" << std::endl 154 << " --node <n>" << std::endl 155 << " node cutoff (0 = none, solution mode)" << std::endl 156 << " --fail <f>" << std::endl 157 << " failure cutoff (0 = none, solution mode)" << std::endl 158 << " --time <ms>" << std::endl 159 << " time (in ms) cutoff (0 = none, solution mode)" << std::endl 160 << " -a, --all-solutions" << std::endl 161 << " print intermediate solutions" << std::endl 162 << " -n <sols>" << std::endl 163 << " number of solutions" << std::endl 164 << std::endl; 165} 166 167class GecodeEngine { 168public: 169 virtual FznSpace* next() = 0; 170 virtual bool stopped() = 0; 171 virtual ~GecodeEngine() {} 172 virtual Gecode::Search::Statistics statistics() = 0; 173}; 174 175template <template <class> class Engine, template <class, template <class> class> class Meta> 176class MetaEngine : public GecodeEngine { 177 Meta<FznSpace, Engine> _e; 178 179public: 180 MetaEngine(FznSpace* s, Search::Options& o) : _e(s, o) {} 181 FznSpace* next() override { return _e.next(); } 182 bool stopped() override { return _e.stopped(); } 183 Gecode::Search::Statistics statistics() override { return _e.statistics(); } 184}; 185 186GecodeSolverInstance::GecodeSolverInstance(Env& env, std::ostream& log, 187 SolverInstanceBase::Options* opt) 188 : SolverInstanceImpl<GecodeSolver>(env, log, opt), 189 _nFoundSolutions(0), 190 currentSpace(nullptr), 191 solution(nullptr), 192 engine(nullptr) { 193 registerConstraints(); 194 _flat = env.flat(); 195} 196 197GecodeSolverInstance::~GecodeSolverInstance() { 198 delete engine; 199 // delete currentSpace; 200 // delete _solution; // TODO: is this necessary? 201} 202 203void GecodeSolverInstance::registerConstraint(const std::string& name, poster p) { 204 std::stringstream ss; 205 ss << "gecode_" << name; 206 _constraintRegistry.add(ss.str(), p); 207 std::stringstream ss2; 208 ss2 << "fzn_" << name; 209 _constraintRegistry.add(ss2.str(), p); 210 // TODO: DO NOT USE global names directly 211 _constraintRegistry.add(name, p); 212} 213 214void GecodeSolverInstance::registerConstraints() { 215 GCLock lock; 216 registerConstraint("all_different_int", GecodeConstraints::p_distinct); 217 registerConstraint("all_different_offset", GecodeConstraints::p_distinct_offset); 218 registerConstraint("all_equal_int", GecodeConstraints::p_all_equal); 219 registerConstraint("int_eq", GecodeConstraints::p_int_eq); 220 registerConstraint("int_ne", GecodeConstraints::p_int_ne); 221 registerConstraint("int_ge", GecodeConstraints::p_int_ge); 222 registerConstraint("int_gt", GecodeConstraints::p_int_gt); 223 registerConstraint("int_le", GecodeConstraints::p_int_le); 224 registerConstraint("int_lt", GecodeConstraints::p_int_lt); 225 registerConstraint("int_eq_reif", GecodeConstraints::p_int_eq_reif); 226 registerConstraint("int_ne_reif", GecodeConstraints::p_int_ne_reif); 227 registerConstraint("int_ge_reif", GecodeConstraints::p_int_ge_reif); 228 registerConstraint("int_gt_reif", GecodeConstraints::p_int_gt_reif); 229 registerConstraint("int_le_reif", GecodeConstraints::p_int_le_reif); 230 registerConstraint("int_lt_reif", GecodeConstraints::p_int_lt_reif); 231 registerConstraint("int_eq_imp", GecodeConstraints::p_int_eq_imp); 232 registerConstraint("int_ne_imp", GecodeConstraints::p_int_ne_imp); 233 registerConstraint("int_ge_imp", GecodeConstraints::p_int_ge_imp); 234 registerConstraint("int_gt_imp", GecodeConstraints::p_int_gt_imp); 235 registerConstraint("int_le_imp", GecodeConstraints::p_int_le_imp); 236 registerConstraint("int_lt_imp", GecodeConstraints::p_int_lt_imp); 237 registerConstraint("int_lin_eq", GecodeConstraints::p_int_lin_eq); 238 registerConstraint("int_lin_eq_reif", GecodeConstraints::p_int_lin_eq_reif); 239 registerConstraint("int_lin_eq_imp", GecodeConstraints::p_int_lin_eq_imp); 240 registerConstraint("int_lin_ne", GecodeConstraints::p_int_lin_ne); 241 registerConstraint("int_lin_ne_reif", GecodeConstraints::p_int_lin_ne_reif); 242 registerConstraint("int_lin_ne_imp", GecodeConstraints::p_int_lin_ne_imp); 243 registerConstraint("int_lin_le", GecodeConstraints::p_int_lin_le); 244 registerConstraint("int_lin_le_reif", GecodeConstraints::p_int_lin_le_reif); 245 registerConstraint("int_lin_le_imp", GecodeConstraints::p_int_lin_le_imp); 246 registerConstraint("int_lin_lt", GecodeConstraints::p_int_lin_lt); 247 registerConstraint("int_lin_lt_reif", GecodeConstraints::p_int_lin_lt_reif); 248 registerConstraint("int_lin_lt_imp", GecodeConstraints::p_int_lin_lt_imp); 249 registerConstraint("int_lin_ge", GecodeConstraints::p_int_lin_ge); 250 registerConstraint("int_lin_ge_reif", GecodeConstraints::p_int_lin_ge_reif); 251 registerConstraint("int_lin_ge_imp", GecodeConstraints::p_int_lin_ge_imp); 252 registerConstraint("int_lin_gt", GecodeConstraints::p_int_lin_gt); 253 registerConstraint("int_lin_gt_reif", GecodeConstraints::p_int_lin_gt_reif); 254 registerConstraint("int_lin_gt_imp", GecodeConstraints::p_int_lin_gt_imp); 255 registerConstraint("int_plus", GecodeConstraints::p_int_plus); 256 registerConstraint("int_minus", GecodeConstraints::p_int_minus); 257 registerConstraint("int_times", GecodeConstraints::p_int_times); 258 registerConstraint("int_div", GecodeConstraints::p_int_div); 259 registerConstraint("int_mod", GecodeConstraints::p_int_mod); 260 registerConstraint("int_min", GecodeConstraints::p_int_min); 261 registerConstraint("int_max", GecodeConstraints::p_int_max); 262 registerConstraint("int_abs", GecodeConstraints::p_abs); 263 registerConstraint("int_negate", GecodeConstraints::p_int_negate); 264 registerConstraint("bool_eq", GecodeConstraints::p_bool_eq); 265 registerConstraint("bool_eq_reif", GecodeConstraints::p_bool_eq_reif); 266 registerConstraint("bool_eq_imp", GecodeConstraints::p_bool_eq_imp); 267 registerConstraint("bool_ne", GecodeConstraints::p_bool_ne); 268 registerConstraint("bool_ne_reif", GecodeConstraints::p_bool_ne_reif); 269 registerConstraint("bool_ne_imp", GecodeConstraints::p_bool_ne_imp); 270 registerConstraint("bool_ge", GecodeConstraints::p_bool_ge); 271 registerConstraint("bool_ge_reif", GecodeConstraints::p_bool_ge_reif); 272 registerConstraint("bool_ge_imp", GecodeConstraints::p_bool_ge_imp); 273 registerConstraint("bool_le", GecodeConstraints::p_bool_le); 274 registerConstraint("bool_le_reif", GecodeConstraints::p_bool_le_reif); 275 registerConstraint("bool_le_imp", GecodeConstraints::p_bool_le_imp); 276 registerConstraint("bool_gt", GecodeConstraints::p_bool_gt); 277 registerConstraint("bool_gt_reif", GecodeConstraints::p_bool_gt_reif); 278 registerConstraint("bool_gt_imp", GecodeConstraints::p_bool_gt_imp); 279 registerConstraint("bool_lt", GecodeConstraints::p_bool_lt); 280 registerConstraint("bool_lt_reif", GecodeConstraints::p_bool_lt_reif); 281 registerConstraint("bool_lt_imp", GecodeConstraints::p_bool_lt_imp); 282 registerConstraint("bool_or", GecodeConstraints::p_bool_or); 283 registerConstraint("bool_or_imp", GecodeConstraints::p_bool_or_imp); 284 registerConstraint("bool_and", GecodeConstraints::p_bool_and); 285 registerConstraint("bool_and_imp", GecodeConstraints::p_bool_and_imp); 286 registerConstraint("bool_xor", GecodeConstraints::p_bool_xor); 287 registerConstraint("bool_xor_imp", GecodeConstraints::p_bool_xor_imp); 288 registerConstraint("array_bool_and", GecodeConstraints::p_array_bool_and); 289 registerConstraint("array_bool_and_imp", GecodeConstraints::p_array_bool_and_imp); 290 registerConstraint("array_bool_or", GecodeConstraints::p_array_bool_or); 291 registerConstraint("array_bool_or_imp", GecodeConstraints::p_array_bool_or_imp); 292 registerConstraint("array_bool_xor", GecodeConstraints::p_array_bool_xor); 293 registerConstraint("array_bool_xor_imp", GecodeConstraints::p_array_bool_xor_imp); 294 registerConstraint("bool_clause", GecodeConstraints::p_array_bool_clause); 295 registerConstraint("bool_clause_reif", GecodeConstraints::p_array_bool_clause_reif); 296 registerConstraint("bool_clause_imp", GecodeConstraints::p_array_bool_clause_imp); 297 registerConstraint("bool_left_imp", GecodeConstraints::p_bool_l_imp); 298 registerConstraint("bool_right_imp", GecodeConstraints::p_bool_r_imp); 299 registerConstraint("bool_not", GecodeConstraints::p_bool_not); 300 registerConstraint("array_int_element", GecodeConstraints::p_array_int_element); 301 registerConstraint("array_var_int_element", GecodeConstraints::p_array_int_element); 302 registerConstraint("array_bool_element", GecodeConstraints::p_array_bool_element); 303 registerConstraint("array_var_bool_element", GecodeConstraints::p_array_bool_element); 304 registerConstraint("bool2int", GecodeConstraints::p_bool2int); 305 registerConstraint("int_in", GecodeConstraints::p_int_in); 306 registerConstraint("int_in_reif", GecodeConstraints::p_int_in_reif); 307 registerConstraint("int_in_imp", GecodeConstraints::p_int_in_imp); 308 309 registerConstraint("array_int_lt", GecodeConstraints::p_array_int_lt); 310 registerConstraint("array_int_lq", GecodeConstraints::p_array_int_lq); 311 registerConstraint("array_bool_lt", GecodeConstraints::p_array_bool_lt); 312 registerConstraint("array_bool_lq", GecodeConstraints::p_array_bool_lq); 313 registerConstraint("count", GecodeConstraints::p_count); 314 registerConstraint("count_reif", GecodeConstraints::p_count_reif); 315 registerConstraint("count_imp", GecodeConstraints::p_count_imp); 316 registerConstraint("at_least_int", GecodeConstraints::p_at_least); 317 registerConstraint("at_most_int", GecodeConstraints::p_at_most); 318 registerConstraint("bin_packing_load", GecodeConstraints::p_bin_packing_load); 319 registerConstraint("global_cardinality", GecodeConstraints::p_global_cardinality); 320 registerConstraint("global_cardinality_closed", GecodeConstraints::p_global_cardinality_closed); 321 registerConstraint("global_cardinality_low_up", GecodeConstraints::p_global_cardinality_low_up); 322 registerConstraint("global_cardinality_low_up_closed", 323 GecodeConstraints::p_global_cardinality_low_up_closed); 324 registerConstraint("array_int_minimum", GecodeConstraints::p_minimum); 325 registerConstraint("array_int_maximum", GecodeConstraints::p_maximum); 326 registerConstraint("minimum_arg_int", GecodeConstraints::p_minimum_arg); 327 registerConstraint("maximum_arg_int", GecodeConstraints::p_maximum_arg); 328 registerConstraint("regular", GecodeConstraints::p_regular); 329 registerConstraint("sort", GecodeConstraints::p_sort); 330 registerConstraint("inverse_offsets", GecodeConstraints::p_inverse_offsets); 331 registerConstraint("increasing_int", GecodeConstraints::p_increasing_int); 332 registerConstraint("increasing_bool", GecodeConstraints::p_increasing_bool); 333 registerConstraint("decreasing_int", GecodeConstraints::p_decreasing_int); 334 registerConstraint("decreasing_bool", GecodeConstraints::p_decreasing_bool); 335 registerConstraint("table_int", GecodeConstraints::p_table_int); 336 registerConstraint("table_bool", GecodeConstraints::p_table_bool); 337 registerConstraint("cumulatives", GecodeConstraints::p_cumulatives); 338 registerConstraint("among_seq_int", GecodeConstraints::p_among_seq_int); 339 registerConstraint("among_seq_bool", GecodeConstraints::p_among_seq_bool); 340 341 registerConstraint("bool_lin_eq", GecodeConstraints::p_bool_lin_eq); 342 registerConstraint("bool_lin_ne", GecodeConstraints::p_bool_lin_ne); 343 registerConstraint("bool_lin_le", GecodeConstraints::p_bool_lin_le); 344 registerConstraint("bool_lin_lt", GecodeConstraints::p_bool_lin_lt); 345 registerConstraint("bool_lin_ge", GecodeConstraints::p_bool_lin_ge); 346 registerConstraint("bool_lin_gt", GecodeConstraints::p_bool_lin_gt); 347 348 registerConstraint("bool_lin_eq_reif", GecodeConstraints::p_bool_lin_eq_reif); 349 registerConstraint("bool_lin_eq_imp", GecodeConstraints::p_bool_lin_eq_imp); 350 registerConstraint("bool_lin_ne_reif", GecodeConstraints::p_bool_lin_ne_reif); 351 registerConstraint("bool_lin_ne_imp", GecodeConstraints::p_bool_lin_ne_imp); 352 registerConstraint("bool_lin_le_reif", GecodeConstraints::p_bool_lin_le_reif); 353 registerConstraint("bool_lin_le_imp", GecodeConstraints::p_bool_lin_le_imp); 354 registerConstraint("bool_lin_lt_reif", GecodeConstraints::p_bool_lin_lt_reif); 355 registerConstraint("bool_lin_lt_imp", GecodeConstraints::p_bool_lin_lt_imp); 356 registerConstraint("bool_lin_ge_reif", GecodeConstraints::p_bool_lin_ge_reif); 357 registerConstraint("bool_lin_ge_imp", GecodeConstraints::p_bool_lin_ge_imp); 358 registerConstraint("bool_lin_gt_reif", GecodeConstraints::p_bool_lin_gt_reif); 359 registerConstraint("bool_lin_gt_imp", GecodeConstraints::p_bool_lin_gt_imp); 360 361 registerConstraint("schedule_unary", GecodeConstraints::p_schedule_unary); 362 registerConstraint("schedule_unary_optional", GecodeConstraints::p_schedule_unary_optional); 363 registerConstraint("schedule_cumulative_optional", GecodeConstraints::p_cumulative_opt); 364 365 registerConstraint("circuit", GecodeConstraints::p_circuit); 366 registerConstraint("circuit_cost_array", GecodeConstraints::p_circuit_cost_array); 367 registerConstraint("circuit_cost", GecodeConstraints::p_circuit_cost); 368 registerConstraint("nooverlap", GecodeConstraints::p_nooverlap); 369 registerConstraint("precede", GecodeConstraints::p_precede); 370 registerConstraint("nvalue", GecodeConstraints::p_nvalue); 371 registerConstraint("among", GecodeConstraints::p_among); 372 registerConstraint("member_int", GecodeConstraints::p_member_int); 373 registerConstraint("member_int_reif", GecodeConstraints::p_member_int_reif); 374 registerConstraint("member_bool", GecodeConstraints::p_member_bool); 375 registerConstraint("member_bool_reif", GecodeConstraints::p_member_bool_reif); 376 377#ifdef GECODE_HAS_FLOAT_VARS 378 registerConstraint("int2float", GecodeConstraints::p_int2float); 379 registerConstraint("float_abs", GecodeConstraints::p_float_abs); 380 registerConstraint("float_sqrt", GecodeConstraints::p_float_sqrt); 381 registerConstraint("float_eq", GecodeConstraints::p_float_eq); 382 registerConstraint("float_eq_reif", GecodeConstraints::p_float_eq_reif); 383 registerConstraint("float_le", GecodeConstraints::p_float_le); 384 registerConstraint("float_le_reif", GecodeConstraints::p_float_le_reif); 385 registerConstraint("float_lt", GecodeConstraints::p_float_lt); 386 registerConstraint("float_lt_reif", GecodeConstraints::p_float_lt_reif); 387 registerConstraint("float_ne", GecodeConstraints::p_float_ne); 388 registerConstraint("float_times", GecodeConstraints::p_float_times); 389 registerConstraint("float_div", GecodeConstraints::p_float_div); 390 registerConstraint("float_plus", GecodeConstraints::p_float_plus); 391 registerConstraint("float_max", GecodeConstraints::p_float_max); 392 registerConstraint("float_min", GecodeConstraints::p_float_min); 393 registerConstraint("float_lin_eq", GecodeConstraints::p_float_lin_eq); 394 registerConstraint("float_lin_eq_reif", GecodeConstraints::p_float_lin_eq_reif); 395 registerConstraint("float_lin_le", GecodeConstraints::p_float_lin_le); 396 registerConstraint("float_lin_le_reif", GecodeConstraints::p_float_lin_le_reif); 397#endif 398#ifdef GECODE_HAS_MPFR 399 registerConstraint("float_acos", GecodeConstraints::p_float_acos); 400 registerConstraint("float_asin", GecodeConstraints::p_float_asin); 401 registerConstraint("float_atan", GecodeConstraints::p_float_atan); 402 registerConstraint("float_cos", GecodeConstraints::p_float_cos); 403 registerConstraint("float_exp", GecodeConstraints::p_float_exp); 404 registerConstraint("float_ln", GecodeConstraints::p_float_ln); 405 registerConstraint("float_log10", GecodeConstraints::p_float_log10); 406 registerConstraint("float_log2", GecodeConstraints::p_float_log2); 407 registerConstraint("float_sin", GecodeConstraints::p_float_sin); 408 registerConstraint("float_tan", GecodeConstraints::p_float_tan); 409#endif 410#ifdef GECODE_HAS_SET_VARS 411 registerConstraint("set_eq", GecodeConstraints::p_set_eq); 412 registerConstraint("set_le", GecodeConstraints::p_set_le); 413 registerConstraint("set_lt", GecodeConstraints::p_set_lt); 414 registerConstraint("equal", GecodeConstraints::p_set_eq); 415 registerConstraint("set_ne", GecodeConstraints::p_set_ne); 416 registerConstraint("set_union", GecodeConstraints::p_set_union); 417 registerConstraint("array_set_element", GecodeConstraints::p_array_set_element); 418 registerConstraint("array_var_set_element", GecodeConstraints::p_array_set_element); 419 registerConstraint("set_intersect", GecodeConstraints::p_set_intersect); 420 registerConstraint("set_diff", GecodeConstraints::p_set_diff); 421 registerConstraint("set_symdiff", GecodeConstraints::p_set_symdiff); 422 registerConstraint("set_subset", GecodeConstraints::p_set_subset); 423 registerConstraint("set_superset", GecodeConstraints::p_set_superset); 424 registerConstraint("set_card", GecodeConstraints::p_set_card); 425 registerConstraint("set_in", GecodeConstraints::p_set_in); 426 registerConstraint("set_eq_reif", GecodeConstraints::p_set_eq_reif); 427 registerConstraint("set_le_reif", GecodeConstraints::p_set_le_reif); 428 registerConstraint("set_lt_reif", GecodeConstraints::p_set_lt_reif); 429 registerConstraint("equal_reif", GecodeConstraints::p_set_eq_reif); 430 registerConstraint("set_ne_reif", GecodeConstraints::p_set_ne_reif); 431 registerConstraint("set_subset_reif", GecodeConstraints::p_set_subset_reif); 432 registerConstraint("set_superset_reif", GecodeConstraints::p_set_superset_reif); 433 registerConstraint("set_in_reif", GecodeConstraints::p_set_in_reif); 434 registerConstraint("set_in_imp", GecodeConstraints::p_set_in_imp); 435 registerConstraint("disjoint", GecodeConstraints::p_set_disjoint); 436 registerConstraint("link_set_to_booleans", GecodeConstraints::p_link_set_to_booleans); 437 registerConstraint("array_set_union", GecodeConstraints::p_array_set_union); 438 registerConstraint("array_set_partition", GecodeConstraints::p_array_set_partition); 439 registerConstraint("set_convex", GecodeConstraints::p_set_convex); 440 registerConstraint("array_set_seq", GecodeConstraints::p_array_set_seq); 441 registerConstraint("array_set_seq_union", GecodeConstraints::p_array_set_seq_union); 442 registerConstraint("array_set_element_union", GecodeConstraints::p_array_set_element_union); 443 registerConstraint("array_set_element_intersect", 444 GecodeConstraints::p_array_set_element_intersect); 445 registerConstraint("array_set_element_intersect_in", 446 GecodeConstraints::p_array_set_element_intersect_in); 447 registerConstraint("array_set_element_partition", 448 GecodeConstraints::p_array_set_element_partition); 449 registerConstraint("int_set_channel", GecodeConstraints::p_int_set_channel); 450 registerConstraint("range", GecodeConstraints::p_range); 451 registerConstraint("set_weights", GecodeConstraints::p_weights); 452 registerConstraint("inverse_set", GecodeConstraints::p_inverse_set); 453 registerConstraint("precede_set", GecodeConstraints::p_precede_set); 454#endif 455} 456 457inline void GecodeSolverInstance::insertVar(Id* id, GecodeVariable gv) { 458 // std::cerr << *id << ": " << id->decl() << std::endl; 459 _variableMap.insert(id->decl()->id(), gv); 460} 461 462inline bool GecodeSolverInstance::valueWithinBounds(double b) { 463 long long int bo = round_to_longlong(b); 464 return bo >= Gecode::Int::Limits::min && bo <= Gecode::Int::Limits::max; 465} 466 467void GecodeSolverInstance::processFlatZinc() { 468 auto& _opt = static_cast<GecodeOptions&>(*_options); 469 _onlyRangeDomains = _opt.onlyRangeDomains; 470 _runSac = _opt.sac; 471 _runShave = _opt.shave; 472 _prePasses = _opt.prePasses; 473 _printStats = _opt.statistics; 474 _allSolutions = _opt.allSolutions; 475 _nMaxSolutions = _opt.nSolutions; 476 _allowUnboundedVars = _opt.allowUnboundedVars; 477 currentSpace = new FznSpace(); 478 479 // iterate over VarDecls of the flat model and create variables 480 for (VarDeclIterator it = _flat->vardecls().begin(); it != _flat->vardecls().end(); ++it) { 481 if (!it->removed() && it->e()->type().isvar()) { 482 // check if it has an output-annotation 483 VarDecl* vd = it->e(); 484 if (!vd->ann().isEmpty()) { 485 if (vd->ann().containsCall(constants().ann.output_array.aststr())) { 486 auto* al = vd->e()->dynamicCast<ArrayLit>(); 487 if (al == nullptr) { 488 std::stringstream ssm; 489 ssm << "GecodeSolverInstance::processFlatZinc: Error: Array without right hand side: " 490 << *vd->id() << std::endl; 491 throw InternalError(ssm.str()); 492 } 493 for (int i = 0; i < al->size(); i++) { 494 if (Id* id = (*al)[i]->dynamicCast<Id>()) { 495 GecodeVariable var = resolveVar(id); 496 if (var.isint()) { 497 currentSpace->ivIntroduced[var.index()] = false; 498 } else if (var.isbool()) { 499 currentSpace->bvIntroduced[var.index()] = false; 500 } else if (var.isfloat()) { 501 currentSpace->fvIntroduced[var.index()] = false; 502 } else if (var.isset()) { 503 currentSpace->svIntroduced[var.index()] = false; 504 } 505 } 506 } 507 _varsWithOutput.push_back(vd); 508 } else if (vd->ann().contains(constants().ann.output_var)) { 509 _varsWithOutput.push_back(vd); 510 } 511 } 512 513 if (it->e()->type().dim() != 0) { 514 // we ignore arrays - all their elements are defined 515 continue; 516 } 517 MiniZinc::TypeInst* ti = it->e()->ti(); 518 bool isDefined; 519 bool isIntroduced = false; 520 521 if (vd->type().isint()) { 522 if (it->e()->e() == nullptr) { // if there is no initialisation expression 523 Expression* domain = ti->domain(); 524 if (domain != nullptr) { 525 IntVar intVar(*this->currentSpace, arg2intset(_env.envi(), domain)); 526 currentSpace->iv.push_back(intVar); 527 insertVar(it->e()->id(), 528 GecodeVariable(GecodeVariable::INT_TYPE, currentSpace->iv.size() - 1)); 529 } else { 530 if (_allowUnboundedVars) { 531 IntVar intVar(*this->currentSpace, Gecode::Int::Limits::min, 532 Gecode::Int::Limits::max); 533 currentSpace->iv.push_back(intVar); 534 insertVar(it->e()->id(), 535 GecodeVariable(GecodeVariable::INT_TYPE, currentSpace->iv.size() - 1)); 536 std::cerr << "% GecodeSolverInstance::processFlatZinc: Warning: Unbounded variable " 537 << *vd->id() 538 << " given maximum integer bounds, this may be incorrect: " << std::endl; 539 } else { 540 std::stringstream ssm; 541 ssm << "GecodeSolverInstance::processFlatZinc: Error: Unbounded variable: " 542 << *vd->id() << ", rerun with --allow-unbounded-vars to add arbitrary bounds." 543 << std::endl; 544 throw InternalError(ssm.str()); 545 } 546 } 547 } else { // there is an initialisation expression 548 Expression* init = it->e()->e(); 549 if (init->isa<Id>() || init->isa<ArrayAccess>()) { 550 // root->iv[root->intVarCount++] = root->iv[*(int*)resolveVar(init)]; 551 GecodeVariable var = resolveVar(init); 552 assert(var.isint()); 553 currentSpace->iv.push_back(var.intVar(currentSpace)); 554 insertVar(it->e()->id(), var); 555 } else { 556 double il = static_cast<double>(init->cast<IntLit>()->v().toInt()); 557 if (valueWithinBounds(il)) { 558 IntVar intVar(*this->currentSpace, static_cast<int>(il), static_cast<int>(il)); 559 currentSpace->iv.push_back(intVar); 560 insertVar(it->e()->id(), 561 GecodeVariable(GecodeVariable::INT_TYPE, currentSpace->iv.size() - 1)); 562 } else { 563 std::stringstream ssm; 564 ssm << "GecodeSolverInstance::processFlatZinc: Error: Unsafe value for Gecode: " << il 565 << std::endl; 566 throw InternalError(ssm.str()); 567 } 568 } 569 } 570 isIntroduced = 571 it->e()->introduced() || 572 (MiniZinc::get_annotation(it->e()->ann(), constants().ann.is_introduced) != nullptr); 573 currentSpace->ivIntroduced.push_back(isIntroduced); 574 isDefined = MiniZinc::get_annotation(it->e()->ann(), 575 constants().ann.is_defined_var->str()) != nullptr; 576 currentSpace->ivDefined.push_back(isDefined); 577 578 } else if (vd->type().isbool()) { 579 double lb = 0; 580 double ub = 1; 581 if (it->e()->e() == nullptr) { // there is NO initialisation expression 582 Expression* domain = ti->domain(); 583 if (domain != nullptr) { 584 IntBounds ib = compute_int_bounds(_env.envi(), domain); 585 lb = static_cast<double>(ib.l.toInt()); 586 ub = static_cast<double>(ib.u.toInt()); 587 } else { 588 lb = 0; 589 ub = 1; 590 } 591 BoolVar boolVar(*this->currentSpace, static_cast<int>(lb), static_cast<int>(ub)); 592 currentSpace->bv.push_back(boolVar); 593 insertVar(it->e()->id(), 594 GecodeVariable(GecodeVariable::BOOL_TYPE, currentSpace->bv.size() - 1)); 595 } else { // there is an initialisation expression 596 Expression* init = it->e()->e(); 597 if (init->isa<Id>() || init->isa<ArrayAccess>()) { 598 // root->bv[root->boolVarCount++] = root->bv[*(int*)resolveVar(init)]; 599 // int index = *(int*) resolveVar(init); 600 GecodeVariable var = resolveVar(init); 601 assert(var.isbool()); 602 currentSpace->bv.push_back(var.boolVar(currentSpace)); 603 insertVar(it->e()->id(), var); 604 } else { 605 auto b = (double)init->cast<BoolLit>()->v(); 606 BoolVar boolVar(*this->currentSpace, b, b); 607 currentSpace->bv.push_back(boolVar); 608 insertVar(it->e()->id(), 609 GecodeVariable(GecodeVariable::BOOL_TYPE, currentSpace->bv.size() - 1)); 610 } 611 } 612 isIntroduced = 613 it->e()->introduced() || 614 (MiniZinc::get_annotation(it->e()->ann(), constants().ann.is_introduced) != nullptr); 615 currentSpace->bvIntroduced.push_back(isIntroduced); 616 isDefined = MiniZinc::get_annotation(it->e()->ann(), 617 constants().ann.is_defined_var->str()) != nullptr; 618 currentSpace->bvDefined.push_back(isDefined); 619#ifdef GECODE_HAS_FLOAT_VARS 620 } else if (vd->type().isfloat()) { 621 if (it->e()->e() == nullptr) { // there is NO initialisation expression 622 Expression* domain = ti->domain(); 623 double lb; 624 double ub; 625 if (domain != nullptr) { 626 FloatBounds fb = compute_float_bounds(_env.envi(), vd->id()); 627 lb = fb.l.toDouble(); 628 ub = fb.u.toDouble(); 629 } else { 630 if (_allowUnboundedVars) { 631 lb = Gecode::Float::Limits::min; 632 ub = Gecode::Float::Limits::max; 633 std::cerr << "%% GecodeSolverInstance::processFlatZinc: Warning: Unbounded variable " 634 << *vd->id() 635 << " given maximum float bounds, this may be incorrect: " << std::endl; 636 } else { 637 std::stringstream ssm; 638 ssm << "GecodeSolverInstance::processFlatZinc: Error: Unbounded variable: " 639 << *vd->id() << ", rerun with --allow-unbounded-vars to add arbitrary bounds." 640 << std::endl; 641 throw InternalError(ssm.str()); 642 } 643 } 644 FloatVar floatVar(*this->currentSpace, lb, ub); 645 currentSpace->fv.push_back(floatVar); 646 insertVar(it->e()->id(), 647 GecodeVariable(GecodeVariable::FLOAT_TYPE, currentSpace->fv.size() - 1)); 648 } else { 649 Expression* init = it->e()->e(); 650 if (init->isa<Id>() || init->isa<ArrayAccess>()) { 651 // root->fv[root->floatVarCount++] = root->fv[*(int*)resolveVar(init)]; 652 GecodeVariable var = resolveVar(init); 653 assert(var.isfloat()); 654 currentSpace->fv.push_back(var.floatVar(currentSpace)); 655 insertVar(it->e()->id(), var); 656 } else { 657 double il = init->cast<FloatLit>()->v().toDouble(); 658 FloatVar floatVar(*this->currentSpace, il, il); 659 currentSpace->fv.push_back(floatVar); 660 insertVar(it->e()->id(), 661 GecodeVariable(GecodeVariable::FLOAT_TYPE, currentSpace->fv.size() - 1)); 662 } 663 } 664 isIntroduced = 665 it->e()->introduced() || 666 (MiniZinc::get_annotation(it->e()->ann(), constants().ann.is_introduced) != nullptr); 667 currentSpace->fvIntroduced.push_back(isIntroduced); 668 isDefined = MiniZinc::get_annotation(it->e()->ann(), 669 constants().ann.is_defined_var->str()) != nullptr; 670 currentSpace->fvDefined.push_back(isDefined); 671#endif 672#ifdef GECODE_HAS_SET_VARS 673 } else if (vd->type().isIntSet()) { 674 Expression* domain = ti->domain(); 675 auto d = arg2intset(_env.envi(), domain); 676 SetVar setVar(*this->currentSpace, Gecode::IntSet::empty, d); 677 currentSpace->sv.push_back(setVar); 678 isIntroduced = 679 it->e()->introduced() || 680 (MiniZinc::get_annotation(it->e()->ann(), constants().ann.is_introduced) != nullptr); 681 currentSpace->svIntroduced.push_back(isIntroduced); 682 isDefined = MiniZinc::get_annotation(it->e()->ann(), 683 constants().ann.is_defined_var->str()) != nullptr; 684 currentSpace->svDefined.push_back(isDefined); 685 insertVar(it->e()->id(), 686 GecodeVariable(GecodeVariable::SET_TYPE, currentSpace->sv.size() - 1)); 687#endif 688 } else { 689 std::stringstream ssm; 690 ssm << "Type " << *ti << " is currently not supported by Gecode." << std::endl; 691 throw InternalError(ssm.str()); 692 } 693 } // end if it is a variable 694 } // end for all var decls 695 696 // post the constraints 697 for (ConstraintIterator it = _flat->constraints().begin(); it != _flat->constraints().end(); 698 ++it) { 699 if (!it->removed()) { 700 if (Call* c = it->e()->dynamicCast<Call>()) { 701 _constraintRegistry.post(c); 702 } 703 } 704 } 705 706 // objective 707 SolveI* si = _flat->solveItem(); 708 currentSpace->solveType = si->st(); 709 if (si->e() != nullptr) { 710 currentSpace->optVarIsInt = (si->e()->type().isvarint()); 711 if (Id* id = si->e()->dynamicCast<Id>()) { 712 if (si->e()->type().isvar()) { 713 GecodeVariable var = resolveVar(id->decl()); 714 if (currentSpace->optVarIsInt) { 715 IntVar intVar = var.intVar(currentSpace); 716 for (int i = 0; i < currentSpace->iv.size(); i++) { 717 if (currentSpace->iv[i].varimp() == intVar.varimp()) { 718 currentSpace->optVarIdx = i; 719 break; 720 } 721 } 722 assert(currentSpace->optVarIdx >= 0); 723#ifdef GECODE_HAS_FLOAT_VARS 724 } else { 725 FloatVar floatVar = var.floatVar(currentSpace); 726 for (int i = 0; i < currentSpace->fv.size(); i++) { 727 if (currentSpace->fv[i].varimp() == floatVar.varimp()) { 728 currentSpace->optVarIdx = i; 729 break; 730 } 731 } 732 assert(currentSpace->optVarIdx >= 0); 733#endif 734 } 735 } 736 } else { // the solve expression has to be a variable/id 737 assert(false); 738 } 739 } 740 741 // std::cout << "DEBUG: at end of processFlatZinc: " << std::endl 742 // << "iv has " << currentSpace->iv.size() << " variables " << std::endl 743 // << "bv has " << currentSpace->bv.size() << " variables " << std::endl 744 // << "fv has " << currentSpace->fv.size() << " variables " << std::endl 745 // << "sv has " << currentSpace->sv.size() << " variables " << std::endl; 746} 747 748Gecode::IntArgs GecodeSolverInstance::arg2intargs(Expression* arg, int offset) { 749 if (!arg->isa<Id>() && !arg->isa<ArrayLit>()) { 750 std::stringstream ssm; 751 ssm << "Invalid argument in arg2intargs: " << *arg; 752 ssm << ". Expected Id or ArrayLit."; 753 throw InternalError(ssm.str()); 754 } 755 ArrayLit* a = 756 arg->isa<Id>() ? arg->cast<Id>()->decl()->e()->cast<ArrayLit>() : arg->cast<ArrayLit>(); 757 IntArgs ia(static_cast<int>(a->size()) + offset); 758 for (int i = offset; (i--) != 0;) { 759 ia[i] = 0; 760 } 761 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 762 ia[i + offset] = (*a)[i]->cast<IntLit>()->v().toInt(); 763 } 764 return ia; 765} 766 767Gecode::IntArgs GecodeSolverInstance::arg2boolargs(Expression* arg, int offset) { 768 if (!arg->isa<Id>() && !arg->isa<ArrayLit>()) { 769 std::stringstream ssm; 770 ssm << "Invalid argument in arg2boolargs: " << *arg; 771 ssm << ". Expected Id or ArrayLit."; 772 throw InternalError(ssm.str()); 773 } 774 ArrayLit* a = 775 arg->isa<Id>() ? arg->cast<Id>()->decl()->e()->cast<ArrayLit>() : arg->cast<ArrayLit>(); 776 IntArgs ia(static_cast<int>(a->size()) + offset); 777 for (int i = offset; (i--) != 0;) { 778 ia[i] = 0; 779 } 780 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 781 ia[i + offset] = static_cast<int>((*a)[i]->cast<BoolLit>()->v()); 782 } 783 return ia; 784} 785 786class GecodeRangeIter { 787public: 788 GecodeSolverInstance& si; 789 IntSetRanges& isr; 790 GecodeRangeIter(GecodeSolverInstance& gsi, IntSetRanges& isr0) : si(gsi), isr(isr0) {} 791 int min() const { 792 long long int val = isr.min().toInt(); 793 if (si.valueWithinBounds(static_cast<double>(val))) { 794 return (int)val; 795 } 796 std::stringstream ssm; 797 ssm << "GecodeRangeIter::min: Error: " << val << " outside 32-bit int." << std::endl; 798 throw InternalError(ssm.str()); 799 } 800 int max() const { 801 long long int val = isr.max().toInt(); 802 if (si.valueWithinBounds(static_cast<double>(val))) { 803 return (int)val; 804 } 805 std::stringstream ssm; 806 ssm << "GecodeRangeIter::max: Error: " << val << " outside 32-bit int." << std::endl; 807 throw InternalError(ssm.str()); 808 } 809 int width() const { return static_cast<int>(isr.width().toInt()); } 810 bool operator()() const { return isr(); } 811 void operator++() { ++isr; } 812}; 813 814Gecode::IntSet GecodeSolverInstance::arg2intset(EnvI& envi, Expression* arg) { 815 GCLock lock; 816 IntSetVal* isv = eval_intset(envi, arg); 817 IntSetRanges isr(isv); 818 GecodeRangeIter isr_g(*this, isr); 819 IntSet d(isr_g); 820 return d; 821} 822IntSetArgs GecodeSolverInstance::arg2intsetargs(EnvI& envi, Expression* arg, int offset) { 823 ArrayLit* a = arg2arraylit(arg); 824 if (a->size() == 0) { 825 IntSetArgs emptyIa(0); 826 return emptyIa; 827 } 828 IntSetArgs ia(static_cast<int>(a->size()) + offset); 829 for (int i = offset; (i--) != 0;) { 830 ia[i] = IntSet::empty; 831 } 832 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 833 ia[i + offset] = arg2intset(envi, (*a)[i]); 834 } 835 return ia; 836} 837 838Gecode::IntVarArgs GecodeSolverInstance::arg2intvarargs(Expression* arg, int offset) { 839 ArrayLit* a = arg2arraylit(arg); 840 if (a->size() == 0) { 841 IntVarArgs emptyIa(0); 842 return emptyIa; 843 } 844 IntVarArgs ia(static_cast<int>(a->size()) + offset); 845 for (int i = offset; (i--) != 0;) { 846 ia[i] = IntVar(*this->currentSpace, 0, 0); 847 } 848 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 849 Expression* e = (*a)[i]; 850 if (e->type().isvar()) { 851 // ia[i+offset] = currentSpace->iv[*(int*)resolveVar(getVarDecl(e))]; 852 GecodeSolver::Variable var = resolveVar(getVarDecl(e)); 853 assert(var.isint()); 854 Gecode::IntVar v = var.intVar(currentSpace); 855 ia[i + offset] = v; 856 } else { 857 long long int value = e->cast<IntLit>()->v().toInt(); 858 if (valueWithinBounds(static_cast<double>(value))) { 859 IntVar iv(*this->currentSpace, static_cast<int>(value), static_cast<int>(value)); 860 ia[i + offset] = iv; 861 } else { 862 std::stringstream ssm; 863 ssm << "GecodeSolverInstance::arg2intvarargs Error: " << value << " outside 32-bit int." 864 << std::endl; 865 throw InternalError(ssm.str()); 866 } 867 } 868 } 869 return ia; 870} 871 872Gecode::BoolVarArgs GecodeSolverInstance::arg2boolvarargs(Expression* arg, int offset, int siv) { 873 ArrayLit* a = arg2arraylit(arg); 874 if (a->length() == 0) { 875 BoolVarArgs emptyIa(0); 876 return emptyIa; 877 } 878 BoolVarArgs ia(static_cast<int>(a->length()) + offset - (siv == -1 ? 0 : 1)); 879 for (int i = offset; (i--) != 0;) { 880 ia[i] = BoolVar(*this->currentSpace, 0, 0); 881 } 882 for (int i = 0; i < static_cast<int>(a->length()); i++) { 883 if (i == siv) { 884 continue; 885 } 886 Expression* e = (*a)[i]; 887 if (e->type().isvar()) { 888 GecodeVariable var = resolveVar(getVarDecl(e)); 889 if (e->type().isvarbool()) { 890 assert(var.isbool()); 891 ia[offset++] = var.boolVar(currentSpace); 892 } else if (e->type().isvarint() && var.hasBoolAlias()) { 893 ia[offset++] = currentSpace->bv[var.boolAliasIndex()]; 894 } else { 895 std::stringstream ssm; 896 ssm << "expected bool-var or alias int var instead of " << *e << " with type " 897 << e->type().toString(env().envi()); 898 throw InternalError(ssm.str()); 899 } 900 } else { 901 if (auto* bl = e->dynamicCast<BoolLit>()) { 902 bool value = bl->v(); 903 BoolVar iv(*this->currentSpace, static_cast<int>(value), static_cast<int>(value)); 904 ia[offset++] = iv; 905 } else { 906 std::stringstream ssm; 907 ssm << "Expected bool literal instead of: " << *e; 908 throw InternalError(ssm.str()); 909 } 910 } 911 } 912 return ia; 913} 914 915Gecode::BoolVar GecodeSolverInstance::arg2boolvar(Expression* e) { 916 BoolVar x0; 917 if (e->type().isvar()) { 918 // x0 = currentSpace->bv[*(int*)resolveVar(getVarDecl(e))]; 919 GecodeVariable var = resolveVar(getVarDecl(e)); 920 assert(var.isbool()); 921 x0 = var.boolVar(currentSpace); 922 } else { 923 if (auto* bl = e->dynamicCast<BoolLit>()) { 924 x0 = BoolVar(*this->currentSpace, static_cast<int>(bl->v()), static_cast<int>(bl->v())); 925 } else { 926 std::stringstream ssm; 927 ssm << "Expected bool literal instead of: " << *e; 928 throw InternalError(ssm.str()); 929 } 930 } 931 return x0; 932} 933 934Gecode::IntVar GecodeSolverInstance::arg2intvar(Expression* e) { 935 IntVar x0; 936 if (e->type().isvar()) { 937 // x0 = currentSpace->iv[*(int*)resolveVar(getVarDecl(e))]; 938 GecodeVariable var = resolveVar(getVarDecl(e)); 939 assert(var.isint()); 940 x0 = var.intVar(currentSpace); 941 } else { 942 IntVal i; 943 if (auto* il = e->dynamicCast<IntLit>()) { 944 i = il->v().toInt(); 945 } else if (auto* bl = e->dynamicCast<BoolLit>()) { 946 i = static_cast<long long>(bl->v()); 947 } else { 948 std::stringstream ssm; 949 ssm << "Expected bool or int literal instead of: " << *e; 950 throw InternalError(ssm.str()); 951 } 952 int ii = static_cast<int>(i.toInt()); 953 x0 = IntVar(*this->currentSpace, ii, ii); 954 } 955 return x0; 956} 957 958ArrayLit* GecodeSolverInstance::arg2arraylit(Expression* arg) { 959 ArrayLit* a; 960 if (Id* id = arg->dynamicCast<Id>()) { 961 VarDecl* vd = id->decl(); 962 if (vd->e() != nullptr) { 963 a = vd->e()->cast<ArrayLit>(); 964 } else { 965 std::vector<Expression*>* array = arrayMap[vd]; 966 std::vector<Expression*> ids; 967 for (auto& i : *array) { 968 ids.push_back(i->cast<VarDecl>()->id()); 969 } 970 a = new ArrayLit(vd->loc(), ids); 971 } 972 } else if (auto* al = arg->dynamicCast<ArrayLit>()) { 973 a = al; 974 } else { 975 std::stringstream ssm; 976 ssm << "Invalid argument in arg2arrayLit: " << *arg; 977 ssm << ". Expected Id or ArrayLit."; 978 throw InternalError(ssm.str()); 979 } 980 return a; 981} 982 983bool GecodeSolverInstance::isBoolArray(ArrayLit* a, int& singleInt) { 984 singleInt = -1; 985 if (a->length() == 0) { 986 return true; 987 } 988 for (int i = static_cast<int>(a->length()); (i--) != 0;) { 989 if ((*a)[i]->type().isbool()) { 990 continue; 991 } 992 if (((*a)[i])->type().isvarint()) { 993 GecodeVariable var = resolveVar(getVarDecl((*a)[i])); 994 if (var.hasBoolAlias()) { 995 if (singleInt != -1) { 996 return false; 997 } 998 singleInt = var.boolAliasIndex(); 999 } else { 1000 return false; 1001 } 1002 } else { 1003 return false; 1004 } 1005 } 1006 return singleInt == -1 || a->length() > 1; 1007} 1008#ifdef GECODE_HAS_SET_VARS 1009SetVar GecodeSolverInstance::arg2setvar(Expression* e) { 1010 SetVar x0; 1011 if (!e->type().isvar()) { 1012 Gecode::IntSet d = arg2intset(_env.envi(), e); 1013 x0 = SetVar(*this->currentSpace, d, d); 1014 } else { 1015 GecodeVariable var = resolveVar(getVarDecl(e)); 1016 assert(var.isset()); 1017 x0 = var.setVar(currentSpace); 1018 } 1019 return x0; 1020} 1021Gecode::SetVarArgs GecodeSolverInstance::arg2setvarargs(Expression* arg, int offset, int doffset, 1022 const Gecode::IntSet& od) { 1023 ArrayLit* a = arg2arraylit(arg); 1024 SetVarArgs ia(static_cast<int>(a->size()) + offset); 1025 for (int i = offset; (i--) != 0;) { 1026 Gecode::IntSet d = i < doffset ? od : Gecode::IntSet::empty; 1027 ia[i] = SetVar(*this->currentSpace, d, d); 1028 } 1029 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 1030 ia[i + offset] = arg2setvar((*a)[i]); 1031 } 1032 return ia; 1033} 1034#endif 1035#ifdef GECODE_HAS_FLOAT_VARS 1036Gecode::FloatValArgs GecodeSolverInstance::arg2floatargs(Expression* arg, int offset) { 1037 assert(arg->isa<Id>() || arg->isa<ArrayLit>()); 1038 ArrayLit* a = 1039 arg->isa<Id>() ? arg->cast<Id>()->decl()->e()->cast<ArrayLit>() : arg->cast<ArrayLit>(); 1040 FloatValArgs fa(static_cast<int>(a->size()) + offset); 1041 for (int i = offset; (i--) != 0;) { 1042 fa[i] = 0.0; 1043 } 1044 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 1045 fa[i + offset] = (*a)[i]->cast<FloatLit>()->v().toDouble(); 1046 } 1047 return fa; 1048} 1049 1050Gecode::FloatVar GecodeSolverInstance::arg2floatvar(Expression* e) { 1051 FloatVar x0; 1052 if (e->type().isvar()) { 1053 GecodeVariable var = resolveVar(getVarDecl(e)); 1054 assert(var.isfloat()); 1055 x0 = var.floatVar(currentSpace); 1056 } else { 1057 FloatVal i; 1058 if (auto* il = e->dynamicCast<IntLit>()) { 1059 i = static_cast<double>(il->v().toInt()); 1060 } else if (auto* bl = e->dynamicCast<BoolLit>()) { 1061 i = static_cast<double>(bl->v()); 1062 } else if (auto* fl = e->dynamicCast<FloatLit>()) { 1063 i = fl->v(); 1064 } else { 1065 std::stringstream ssm; 1066 ssm << "Expected bool, int or float literal instead of: " << *e; 1067 throw InternalError(ssm.str()); 1068 } 1069 x0 = FloatVar(*this->currentSpace, i.toDouble(), i.toDouble()); 1070 } 1071 return x0; 1072} 1073 1074Gecode::FloatVarArgs GecodeSolverInstance::arg2floatvarargs(Expression* arg, int offset) { 1075 ArrayLit* a = arg2arraylit(arg); 1076 if (a->size() == 0) { 1077 FloatVarArgs emptyFa(0); 1078 return emptyFa; 1079 } 1080 FloatVarArgs fa(static_cast<int>(a->size()) + offset); 1081 for (int i = offset; (i--) != 0;) { 1082 fa[i] = FloatVar(*this->currentSpace, 0.0, 0.0); 1083 } 1084 for (int i = static_cast<int>(a->size()); (i--) != 0;) { 1085 Expression* e = (*a)[i]; 1086 if (e->type().isvar()) { 1087 GecodeVariable var = resolveVar(getVarDecl(e)); 1088 assert(var.isfloat()); 1089 fa[i + offset] = var.floatVar(currentSpace); 1090 } else { 1091 if (auto* fl = e->dynamicCast<FloatLit>()) { 1092 double value = fl->v().toDouble(); 1093 FloatVar fv(*this->currentSpace, value, value); 1094 fa[i + offset] = fv; 1095 } else { 1096 std::stringstream ssm; 1097 ssm << "Expected float literal instead of: " << *e; 1098 throw InternalError(ssm.str()); 1099 } 1100 } 1101 } 1102 return fa; 1103} 1104#endif 1105 1106MZ_IntConLevel GecodeSolverInstance::ann2icl(const Annotation& ann) { 1107 if (!ann.isEmpty()) { 1108 if (get_annotation(ann, "val") != nullptr) { 1109 return MZ_ICL_VAL; 1110 } 1111 if (get_annotation(ann, "domain") != nullptr) { 1112 return MZ_ICL_DOM; 1113 } 1114 if ((get_annotation(ann, "bounds") != nullptr) || (get_annotation(ann, "boundsR") != nullptr) || 1115 (get_annotation(ann, "boundsD") != nullptr) || 1116 (get_annotation(ann, "boundsZ") != nullptr)) { 1117 return MZ_ICL_BND; 1118 } 1119 } 1120 return MZ_ICL_DEF; 1121} 1122 1123VarDecl* GecodeSolverInstance::getVarDecl(Expression* expr) { 1124 VarDecl* vd = nullptr; 1125 if ((vd = expr->dynamicCast<VarDecl>()) != nullptr) { 1126 vd = expr->cast<VarDecl>(); 1127 } else if (Id* id = expr->dynamicCast<Id>()) { 1128 vd = id->decl(); 1129 } else if (auto* aa = expr->dynamicCast<ArrayAccess>()) { 1130 vd = resolveArrayAccess(aa); 1131 } else { 1132 std::stringstream ssm; 1133 ssm << "Can not extract vardecl from " << *expr; 1134 throw InternalError(ssm.str()); 1135 } 1136 return vd; 1137} 1138 1139VarDecl* GecodeSolverInstance::resolveArrayAccess(ArrayAccess* aa) { 1140 VarDecl* vd = aa->v()->cast<Id>()->decl(); 1141 long long int idx = aa->idx()[0]->cast<IntLit>()->v().toInt(); 1142 return resolveArrayAccess(vd, idx); 1143} 1144 1145VarDecl* GecodeSolverInstance::resolveArrayAccess(VarDecl* vd, long long int index) { 1146 auto it = arrayMap.find(vd); 1147 if (it != arrayMap.end()) { 1148 std::vector<Expression*>* exprs = it->second; 1149 Expression* expr = (*exprs)[index - 1]; 1150 return expr->cast<VarDecl>(); 1151 } 1152 std::stringstream ssm; 1153 ssm << "Unknown array: " << vd->id(); 1154 throw InternalError(ssm.str()); 1155} 1156 1157GecodeSolver::Variable GecodeSolverInstance::resolveVar(Expression* e) { 1158 if (Id* id = e->dynamicCast<Id>()) { 1159 return _variableMap.get(id->decl()->id()); // lookupVar(id->decl()); 1160 } 1161 if (auto* vd = e->dynamicCast<VarDecl>()) { 1162 return _variableMap.get(vd->id()->decl()->id()); 1163 } 1164 if (auto* aa = e->dynamicCast<ArrayAccess>()) { 1165 return _variableMap.get(resolveArrayAccess(aa)->id()->decl()->id()); 1166 } 1167 std::stringstream ssm; 1168 ssm << "Expected Id, VarDecl or ArrayAccess instead of \"" << *e << "\""; 1169 throw InternalError(ssm.str()); 1170} 1171 1172SolverInstance::Status GecodeSolverInstance::next() { 1173 GCLock lock; 1174 prepareEngine(); 1175 1176 solution = engine->next(); 1177 1178 if (solution != nullptr) { 1179 assignSolutionToOutput(); 1180 return SolverInstance::SAT; 1181 } 1182 if (engine->stopped()) { 1183 return SolverInstance::UNKNOWN; 1184 } 1185 return SolverInstance::UNSAT; 1186} 1187 1188void GecodeSolverInstance::resetSolver() { 1189 assert(false); // TODO: implement 1190} 1191 1192Expression* GecodeSolverInstance::getSolutionValue(Id* id) { 1193 id = id->decl()->id(); 1194 if (id->type().isvar()) { 1195 GecodeVariable var = resolveVar(id->decl()->id()); 1196#ifdef GECODE_HAS_SET_VARS 1197 if (id->type().isSet()) { 1198 SetVar& sv = var.setVar(solution); 1199 assert(sv.assigned()); 1200 SetVarGlbRanges svr(sv); 1201 assert(svr()); 1202 1203 IntVal mi = svr.min(); 1204 IntVal ma = svr.max(); 1205 ++svr; 1206 vector<IntVal> vals; 1207 if (svr()) { 1208 SetVarGlbValues svv(sv); 1209 IntVal i = svv.val(); 1210 vals.push_back(i); 1211 ++svv; 1212 for (; svv(); ++svv) { 1213 vals.emplace_back(svv.val()); 1214 } 1215 return new SetLit(Location().introduce(), IntSetVal::a(vals)); 1216 } 1217 return new SetLit(Location().introduce(), IntSetVal::a(mi, ma)); 1218 } 1219#endif 1220 switch (id->type().bt()) { 1221 case Type::BT_INT: 1222 assert(var.intVar(solution).assigned()); 1223 return IntLit::a(var.intVar(solution).val()); 1224 case Type::BT_BOOL: 1225 assert(var.boolVar(solution).assigned()); 1226 return constants().boollit(var.boolVar(solution).val() != 0); 1227#ifdef GECODE_HAS_FLOAT_VARS 1228 case Type::BT_FLOAT: 1229 assert(var.floatVar(solution).assigned()); 1230 return FloatLit::a(var.floatVar(solution).val().med()); 1231#endif 1232 default: 1233 return nullptr; 1234 } 1235 } else { 1236 return id->decl()->e(); 1237 } 1238} 1239 1240void GecodeSolverInstance::prepareEngine() { 1241 GCLock lock; 1242 auto& _opt = static_cast<GecodeOptions&>(*_options); 1243 if (engine == nullptr) { 1244 // TODO: check what we need to do options-wise 1245 std::vector<Expression*> branch_vars; 1246 std::vector<Expression*> solve_args; 1247 Expression* solveExpr = _flat->solveItem()->e(); 1248 Expression* optSearch = nullptr; 1249 1250 switch (currentSpace->solveType) { 1251 case MiniZinc::SolveI::SolveType::ST_MIN: 1252 assert(solveExpr != nullptr); 1253 branch_vars.push_back(solveExpr); 1254 solve_args.push_back(new ArrayLit(Location(), branch_vars)); 1255 if (!currentSpace->optVarIsInt) { // TODO: why?? 1256 solve_args.push_back(FloatLit::a(0.0)); 1257 } 1258 solve_args.push_back(new Id(Location(), "input_order", nullptr)); 1259 solve_args.push_back(new Id( 1260 Location(), currentSpace->optVarIsInt ? "indomain_min" : "indomain_split", nullptr)); 1261 solve_args.push_back(new Id(Location(), "complete", nullptr)); 1262 optSearch = new Call(Location(), currentSpace->optVarIsInt ? "int_search" : "float_search", 1263 solve_args); 1264 break; 1265 case MiniZinc::SolveI::SolveType::ST_MAX: 1266 branch_vars.push_back(solveExpr); 1267 solve_args.push_back(new ArrayLit(Location(), branch_vars)); 1268 if (!currentSpace->optVarIsInt) { 1269 solve_args.push_back(FloatLit::a(0.0)); 1270 } 1271 solve_args.push_back(new Id(Location(), "input_order", nullptr)); 1272 solve_args.push_back( 1273 new Id(Location(), 1274 currentSpace->optVarIsInt ? "indomain_max" : "indomain_split_reverse", nullptr)); 1275 solve_args.push_back(new Id(Location(), "complete", nullptr)); 1276 optSearch = new Call(Location(), currentSpace->optVarIsInt ? "int_search" : "float_search", 1277 solve_args); 1278 break; 1279 case MiniZinc::SolveI::SolveType::ST_SAT: 1280 break; 1281 default: 1282 assert(false); 1283 } 1284 1285 engineOptions.c_d = _opt.c_d; 1286 engineOptions.a_d = _opt.a_d; 1287 1288 int seed = _opt.seed; 1289 double decay = _opt.decay; 1290 1291 createBranchers(_flat->solveItem()->ann(), optSearch, seed, decay, false, /* ignoreUnknown */ 1292 std::cerr); 1293 1294 int nodeStop = _opt.nodes; 1295 int failStop = _opt.fails; 1296 int timeStop = _opt.time; 1297 1298 engineOptions.stop = Driver::CombinedStop::create(nodeStop, failStop, timeStop, false); 1299 1300 // TODO: add presolving part 1301 if (currentSpace->solveType == MiniZinc::SolveI::SolveType::ST_SAT) { 1302 engine = new MetaEngine<DFS, Driver::EngineToMeta>(this->currentSpace, engineOptions); 1303 } else { 1304 engine = new MetaEngine<BAB, Driver::EngineToMeta>(this->currentSpace, engineOptions); 1305 } 1306 } 1307} 1308 1309void GecodeSolverInstance::printStatistics() { 1310 EnvI& env = _env.envi(); 1311 Gecode::Search::Statistics stat = engine->statistics(); 1312 env.outstream << "%%%mzn-stat: variables=" 1313 << (currentSpace->iv.size() + currentSpace->bv.size() + currentSpace->sv.size()) 1314 << std::endl 1315 << "%%%mzn-stat: propagators=" << Gecode::PropagatorGroup::all.size(*currentSpace) 1316 << endl 1317 << "%%%mzn-stat: propagations=" << stat.propagate << std::endl 1318 << "%%%mzn-stat: nodes=" << stat.node << std::endl 1319 << "%%%mzn-stat: failures=" << stat.fail << std::endl 1320 << "%%%mzn-stat: restarts=" << stat.restart << std::endl 1321 << "%%%mzn-stat: peak_depth=" << stat.depth << std::endl 1322 << "%%%mzn-stat-end" << std::endl; 1323} 1324 1325void GecodeSolverInstance::processSolution(bool last_sol) { 1326 if (solution != nullptr) { 1327 assignSolutionToOutput(); 1328 printSolution(); 1329 if (currentSpace->solveType == MiniZinc::SolveI::SolveType::ST_SAT) { 1330 if (engine->stopped() || !last_sol) { 1331 _status = SolverInstance::SAT; 1332 } else { 1333 _status = SolverInstance::OPT; 1334 } 1335 } else { 1336 if (engine->stopped()) { 1337 Gecode::Search::Statistics stat = engine->statistics(); 1338 auto* cs = static_cast<Driver::CombinedStop*>(engineOptions.stop); 1339 std::cerr << "% GecodeSolverInstance: "; 1340 int r = cs->reason(stat, engineOptions); 1341 if ((r & Driver::CombinedStop::SR_INT) != 0) { 1342 std::cerr << "user interrupt " << std::endl; 1343 } else { 1344 if ((r & Driver::CombinedStop::SR_NODE) != 0) { 1345 _statusReason = SolverInstance::SR_LIMIT; 1346 std::cerr << "node "; 1347 } 1348 if ((r & Driver::CombinedStop::SR_FAIL) != 0) { 1349 _statusReason = SolverInstance::SR_LIMIT; 1350 std::cerr << "failure "; 1351 } 1352 if ((r & Driver::CombinedStop::SR_TIME) != 0) { 1353 _statusReason = SolverInstance::SR_LIMIT; 1354 std::cerr << "time "; 1355 } 1356 std::cerr << "limit reached" << std::endl << std::endl; 1357 } 1358 if (_nFoundSolutions > 0) { 1359 _status = SolverInstance::SAT; 1360 } else { 1361 _status = SolverInstance::UNKNOWN; 1362 } 1363 } else { 1364 _status = last_sol ? SolverInstance::OPT : SolverInstance::SAT; 1365 } 1366 } 1367 } else { 1368 if (engine->stopped()) { 1369 _status = SolverInstance::UNKNOWN; 1370 } else { 1371 _status = SolverInstance::UNSAT; 1372 } 1373 } 1374} 1375 1376SolverInstanceBase::Status GecodeSolverInstance::solve() { 1377 GCLock lock; 1378 SolverInstanceBase::Status ret; 1379 1380 prepareEngine(); 1381 1382 if (_runSac || _runShave) { 1383 presolve(); 1384 } 1385 1386 int n_max_solutions = _nMaxSolutions; 1387 if (n_max_solutions == -1) { 1388 if (_allSolutions) { 1389 n_max_solutions = 0; 1390 } else if (currentSpace->solveType == MiniZinc::SolveI::SolveType::ST_SAT) { 1391 n_max_solutions = 1; 1392 } 1393 } 1394 1395 FznSpace* next_sol = engine->next(); 1396 while (next_sol != nullptr) { 1397 delete solution; 1398 solution = next_sol; 1399 _nFoundSolutions++; 1400 1401 if (n_max_solutions == 0 || _nFoundSolutions <= n_max_solutions) { 1402 processSolution(); 1403 if (_printStats) { 1404 printStatistics(); 1405 } 1406 } 1407 if (_nFoundSolutions == n_max_solutions) { 1408 break; 1409 } 1410 next_sol = engine->next(); 1411 } 1412 if (currentSpace->solveType != MiniZinc::SolveI::SolveType::ST_SAT) { 1413 if (n_max_solutions == -1) { 1414 // Print last solution 1415 processSolution(next_sol == nullptr); 1416 if (_printStats) { 1417 printStatistics(); 1418 } 1419 } 1420 } 1421 if (next_sol == nullptr) { 1422 if (solution != nullptr) { 1423 ret = engine->stopped() ? SolverInstance::SAT : SolverInstance::OPT; 1424 } else { 1425 ret = engine->stopped() ? SolverInstance::UNKNOWN : SolverInstance::UNSAT; 1426 } 1427 } else { 1428 ret = SolverInstance::SAT; 1429 } 1430 _pS2Out->stats.nFails = engine->statistics().fail; 1431 _pS2Out->stats.nNodes = engine->statistics().node; 1432 delete engine; 1433 engine = nullptr; 1434 return ret; 1435} 1436 1437class IntVarComp { 1438public: 1439 std::vector<Gecode::IntVar> iv; 1440 IntVarComp(std::vector<Gecode::IntVar> b) { iv = std::move(b); } 1441 int operator()(int a, int b) { return static_cast<int>(iv[a].size() < iv[b].size()); } 1442}; 1443 1444class IntVarRangesBwd : public Int::IntVarImpBwd { 1445public: 1446 IntVarRangesBwd() {} 1447 IntVarRangesBwd(const IntVar& x) : Int::IntVarImpBwd(x.varimp()) {} 1448 static void init(const IntVar& x) { Int::IntVarImpBwd(x.varimp()); } 1449}; 1450 1451bool GecodeSolverInstance::sac(bool toFixedPoint = false, bool shaving = false) const { 1452 if (currentSpace->status() == SS_FAILED) { 1453 return false; 1454 } 1455 bool modified; 1456 std::vector<int> sorted_iv; 1457 1458 for (unsigned int i = 0; i < currentSpace->iv.size(); i++) { 1459 if (!currentSpace->iv[i].assigned()) { 1460 sorted_iv.push_back(i); 1461 } 1462 } 1463 IntVarComp ivc(currentSpace->iv); 1464 sort(sorted_iv.begin(), sorted_iv.end(), ivc); 1465 1466 do { 1467 modified = false; 1468 for (unsigned int idx = 0; idx < currentSpace->bv.size(); idx++) { 1469 BoolVar bvar = currentSpace->bv[idx]; 1470 if (!bvar.assigned()) { 1471 for (int val = bvar.min(); val <= bvar.max(); ++val) { 1472 auto* f = static_cast<FznSpace*>(currentSpace->clone()); 1473 rel(*f, f->bv[idx], IRT_EQ, val); 1474 if (f->status() == SS_FAILED) { 1475 rel(*currentSpace, bvar, IRT_NQ, val); 1476 modified = true; 1477 if (currentSpace->status() == SS_FAILED) { 1478 return false; 1479 } 1480 } 1481 delete f; 1482 } 1483 } 1484 } 1485 1486 for (unsigned int idx : sorted_iv) { 1487 IntVar ivar = currentSpace->iv[idx]; 1488 bool tight = false; 1489 int nnq = 0; 1490 int fwd_min; 1491 IntArgs nq(static_cast<int>(ivar.size())); 1492 for (IntVarValues vv(ivar); vv() && !tight; ++vv) { 1493 auto* f = static_cast<FznSpace*>(currentSpace->clone()); 1494 rel(*f, f->iv[idx], IRT_EQ, vv.val()); 1495 if (f->status() == SS_FAILED) { 1496 nq[nnq++] = vv.val(); 1497 } else { 1498 fwd_min = vv.val(); 1499 tight = shaving; 1500 } 1501 delete f; 1502 } 1503 if (shaving) { 1504 tight = false; 1505 for (IntVarRangesBwd vr(ivar); vr() && !tight; ++vr) { 1506 for (int i = vr.max(); i >= vr.min() && i >= fwd_min; i--) { 1507 auto* f = static_cast<FznSpace*>(currentSpace->clone()); 1508 rel(*f, f->iv[idx], IRT_EQ, i); 1509 if (f->status() == SS_FAILED) { 1510 nq[nnq++] = i; 1511 } else { 1512 tight = true; 1513 } 1514 delete f; 1515 } 1516 } 1517 } 1518 if (nnq != 0U) { 1519 modified = true; 1520 } 1521 while ((nnq--) != 0U) { 1522 rel(*currentSpace, ivar, IRT_NQ, nq[nnq]); 1523 } 1524 if (currentSpace->status() == SS_FAILED) { 1525 return false; 1526 } 1527 } 1528 } while (toFixedPoint && modified); 1529 return true; 1530} 1531 1532bool GecodeSolverInstance::presolve(Model* originalModel) { 1533 GCLock lock; 1534 if (currentSpace->status() == SS_FAILED) { 1535 return false; 1536 } 1537 // run SAC? 1538 if (_runSac || _runShave) { 1539 unsigned int iters = _prePasses; 1540 if (iters != 0U) { 1541 for (unsigned int i = 0; i < iters; i++) { 1542 sac(false, _runShave); 1543 } 1544 } else { 1545 sac(true, _runShave); 1546 } 1547 } 1548 1549 if (originalModel != nullptr) { 1550 ASTStringMap<VarDecl*> vds; 1551 for (VarDeclIterator it = originalModel->vardecls().begin(); 1552 it != originalModel->vardecls().end(); ++it) { 1553 VarDecl* vd = it->e(); 1554 vds[vd->id()->str()] = vd; 1555 } 1556 1557 IdMap<GecodeVariable>::iterator it; 1558 for (it = _variableMap.begin(); it != _variableMap.end(); it++) { 1559 VarDecl* vd = it->first->decl(); 1560 long long int old_domsize = 0; 1561 bool holes = false; 1562 1563 if (vd->ti()->domain() != nullptr) { 1564 if (vd->type().isint()) { 1565 IntBounds old_bounds = compute_int_bounds(_env.envi(), vd->id()); 1566 long long int old_rangesize = abs(old_bounds.u.toInt() - old_bounds.l.toInt()); 1567 if (vd->ti()->domain()->isa<SetLit>()) { 1568 old_domsize = arg2intset(_env.envi(), vd->ti()->domain()).size(); 1569 } else { 1570 old_domsize = old_rangesize + 1; 1571 } 1572 holes = old_domsize < old_rangesize + 1; 1573 } 1574 } 1575 1576 ASTString name = it->first->str(); 1577 1578 if (vds.find(name) != vds.end()) { 1579 VarDecl* nvd = vds[name]; 1580 Type::BaseType bt = vd->type().bt(); 1581 if (bt == Type::BaseType::BT_INT && vd->type().st() == Type::ST_PLAIN) { 1582 IntVar intvar = it->second.intVar(currentSpace); 1583 const long long int l = intvar.min(); 1584 const long long int u = intvar.max(); 1585 1586 if (l == u) { 1587 if (nvd->e() != nullptr) { 1588 nvd->ti()->domain(new SetLit(nvd->loc(), IntSetVal::a(l, u))); 1589 } else { 1590 nvd->type(Type::parint()); 1591 nvd->ti(new TypeInst(nvd->loc(), Type::parint())); 1592 nvd->e(IntLit::a(l)); 1593 } 1594 } else if (!(l == Gecode::Int::Limits::min || u == Gecode::Int::Limits::max)) { 1595 if (_onlyRangeDomains && !holes) { 1596 nvd->ti()->domain(new SetLit(nvd->loc(), IntSetVal::a(l, u))); 1597 } else { 1598 IntVarRanges ivr(intvar); 1599 nvd->ti()->domain(new SetLit(nvd->loc(), IntSetVal::ai(ivr))); 1600 } 1601 } 1602 } else if (bt == Type::BaseType::BT_BOOL) { 1603 BoolVar boolvar = it->second.boolVar(currentSpace); 1604 int l = boolvar.min(); 1605 int u = boolvar.max(); 1606 if (l == u) { 1607 if (nvd->e() != nullptr) { 1608 nvd->ti()->domain(constants().boollit(l != 0)); 1609 } else { 1610 nvd->type(Type::parbool()); 1611 nvd->ti(new TypeInst(nvd->loc(), Type::parbool())); 1612 nvd->e(new BoolLit(nvd->loc(), l != 0)); 1613 } 1614 } 1615#ifdef GECODE_HAS_FLOAT_VAR 1616 } else if (bt == Type::BaseType::BT_FLOAT) { 1617 Gecode::FloatVar floatvar = it->second.floatVar(currentSpace); 1618 if (floatvar.assigned() && !nvd->e()) { 1619 FloatNum l = floatvar.min(); 1620 nvd->type(Type::parfloat()); 1621 nvd->ti(new TypeInst(nvd->loc(), Type::parfloat())); 1622 nvd->e(FloatLit::a(l)); 1623 } else { 1624 FloatNum l = floatvar.min(), u = floatvar.max(); 1625 nvd->ti()->domain(new SetLit(nvd->loc(), FloatSetVal::a(l, u))); 1626 } 1627#endif 1628 } 1629 } 1630 } 1631 } 1632 return true; 1633} 1634 1635void GecodeSolverInstance::setSearchStrategyFromAnnotation( 1636 std::vector<Expression*> flatAnn, std::vector<bool>& iv_searched, 1637 std::vector<bool>& bv_searched, 1638#ifdef GECODE_HAS_SET_VARS 1639 std::vector<bool>& sv_searched, 1640#endif 1641#ifdef GECODE_HAS_FLOAT_VARS 1642 std::vector<bool>& fv_searched, 1643#endif 1644 TieBreak<IntVarBranch>& def_int_varsel, IntValBranch& def_int_valsel, 1645 TieBreak<BoolVarBranch>& def_bool_varsel, BoolValBranch& def_bool_valsel, 1646#ifdef GECODE_HAS_SET_VARS 1647 SetVarBranch& def_set_varsel, SetValBranch& def_set_valsel, 1648#endif 1649#ifdef GECODE_HAS_FLOAT_VARS 1650 TieBreak<FloatVarBranch>& def_float_varsel, FloatValBranch& def_float_valsel, 1651#endif 1652 Rnd& rnd, double decay, bool ignoreUnknown, std::ostream& err) { 1653 for (auto& i : flatAnn) { 1654 if (i->isa<Call>() && i->cast<Call>()->id() == "gecode_search") { 1655 // Call* c = flatAnn[i]->cast<Call>(); 1656 // branchWithPlugin(c->args); 1657 std::cerr << "WARNING: Not supporting search annotation \"gecode_search\" yet." << std::endl; 1658 return; 1659 } 1660 if (i->isa<Call>() && i->cast<Call>()->id() == "int_search") { 1661 Call* call = i->cast<Call>(); 1662 ArrayLit* vars = arg2arraylit(call->arg(0)); 1663 if (vars->size() == 0) { // empty array 1664 std::cerr << "WARNING: trying to branch on empty array in search annotation: " << *call 1665 << std::endl; 1666 continue; 1667 } 1668 int k = static_cast<int>(vars->size()); 1669 for (int i = static_cast<int>(vars->size()); (i--) != 0;) { 1670 if (!(*vars)[i]->type().isvarint()) { 1671 k--; 1672 } 1673 } 1674 IntVarArgs va(k); 1675 std::vector<ASTString> names; 1676 k = 0; 1677 for (unsigned int i = 0; i < vars->size(); i++) { 1678 if (!(*vars)[i]->type().isvarint()) { 1679 continue; 1680 } 1681 unsigned int idx = resolveVar(getVarDecl((*vars)[i])).index(); 1682 va[k++] = currentSpace->iv[idx]; 1683 iv_searched[idx] = true; 1684 names.push_back(getVarDecl((*vars)[i])->id()->str()); 1685 } 1686 std::string r0; 1687 std::string r1; 1688 // BrancherHandle bh = 1689 branch(*currentSpace, va, ann2ivarsel(call->arg(1)->cast<Id>()->str(), rnd, decay), 1690 ann2ivalsel(call->arg(2)->cast<Id>()->str(), r0, r1, rnd), nullptr 1691 //,&varValPrint<IntVar> 1692 ); 1693 // branchInfo.add(bh,r0,r1,names); 1694 } // end int_search 1695 else if (i->isa<Call>() && i->cast<Call>()->id() == "int_assign") { 1696 Call* call = i->dynamicCast<Call>(); 1697 ArrayLit* vars = arg2arraylit(call->arg(0)); 1698 int k = static_cast<int>(vars->size()); 1699 for (int i = static_cast<int>(vars->size()); (i--) != 0;) { 1700 if (!((*vars)[i])->type().isvarint()) { 1701 k--; 1702 } 1703 } 1704 IntVarArgs va(k); 1705 k = 0; 1706 for (unsigned int i = 0; i < vars->size(); i++) { 1707 if (!((*vars)[i])->type().isvarint()) { 1708 continue; 1709 } 1710 unsigned int idx = resolveVar(getVarDecl((*vars)[i])).index(); 1711 va[k++] = currentSpace->iv[idx]; 1712 iv_searched[idx] = true; 1713 } 1714 assign(*currentSpace, va, ann2asnivalsel(call->arg(1)->cast<Id>()->str(), rnd), nullptr 1715 //&varValPrint<IntVar> 1716 ); 1717 } else if (i->isa<Call>() && i->cast<Call>()->id() == "bool_search") { 1718 Call* call = i->dynamicCast<Call>(); 1719 ArrayLit* vars = arg2arraylit(call->arg(0)); 1720 int k = static_cast<int>(vars->size()); 1721 for (int i = static_cast<int>(vars->size()); (i--) != 0;) { 1722 if (!((*vars)[i])->type().isvarbool()) { 1723 k--; 1724 } 1725 } 1726 BoolVarArgs va(k); 1727 k = 0; 1728 std::vector<ASTString> names; 1729 for (unsigned int i = 0; i < vars->size(); i++) { 1730 if (!((*vars)[i])->type().isvarbool()) { 1731 continue; 1732 } 1733 unsigned int idx = resolveVar(getVarDecl((*vars)[i])).index(); 1734 va[k++] = currentSpace->bv[idx]; 1735 bv_searched[idx] = true; 1736 names.push_back(getVarDecl((*vars)[i])->id()->str()); 1737 } 1738 1739 std::string r0; 1740 std::string r1; 1741 // BrancherHandle bh = 1742 branch(*currentSpace, va, ann2bvarsel(call->arg(1)->cast<Id>()->str(), rnd, decay), 1743 ann2bvalsel(call->arg(2)->cast<Id>()->str(), r0, r1, rnd), nullptr //, 1744 //&varValPrint<BoolVar> 1745 ); 1746 // branchInfo.add(bh,r0,r1,names); 1747 } else if (i->isa<Call>() && i->cast<Call>()->id() == "int_default_search") { 1748 Call* call = i->dynamicCast<Call>(); 1749 def_int_varsel = ann2ivarsel(call->arg(0)->cast<Id>()->str(), rnd, decay); 1750 std::string r0; 1751 def_int_valsel = ann2ivalsel(call->arg(1)->cast<Id>()->str(), r0, r0, rnd); 1752 } else if (i->isa<Call>() && i->cast<Call>()->id() == "bool_default_search") { 1753 Call* call = i->dynamicCast<Call>(); 1754 std::string r0; 1755 def_bool_varsel = ann2bvarsel(call->arg(0)->cast<Id>()->str(), rnd, decay); 1756 def_bool_valsel = ann2bvalsel(call->arg(1)->cast<Id>()->str(), r0, r0, rnd); 1757 } else if (i->isa<Call>() && i->cast<Call>()->id() == "set_search") { 1758#ifdef GECODE_HAS_SET_VARS 1759 Call* call = i->dynamicCast<Call>(); 1760 ArrayLit* vars = arg2arraylit(call->arg(0)); 1761 int k = static_cast<int>(vars->size()); 1762 for (int i = static_cast<int>(vars->size()); (i--) != 0;) { 1763 if (!((*vars)[i])->type().isSet() || !((*vars)[i])->type().isvar()) { 1764 k--; 1765 } 1766 } 1767 SetVarArgs va(k); 1768 k = 0; 1769 std::vector<ASTString> names; 1770 for (unsigned int i = 0; i < vars->size(); i++) { 1771 if (!((*vars)[i])->type().isSet() || !((*vars)[i])->type().isvar()) { 1772 continue; 1773 } 1774 unsigned int idx = resolveVar(getVarDecl((*vars)[i])).index(); 1775 va[k++] = currentSpace->sv[idx]; 1776 sv_searched[idx] = true; 1777 names.push_back(getVarDecl((*vars)[i])->id()->str()); 1778 } 1779 std::string r0; 1780 std::string r1; 1781 // BrancherHandle bh = 1782 branch(*currentSpace, va, ann2svarsel(call->arg(1)->cast<Id>()->str(), rnd, decay), 1783 ann2svalsel(call->arg(2)->cast<Id>()->str(), r0, r1, rnd), 1784 nullptr //, 1785 //&varValPrint<SetVar> 1786 ); 1787 // branchInfo.add(bh,r0,r1,names); 1788#else 1789 if (!ignoreUnknown) { 1790 err << "Warning, ignored search annotation: "; 1791 flatAnn[i]->print(err); 1792 err << std::endl; 1793 } 1794#endif 1795 } else if (i->isa<Call>() && i->cast<Call>()->id() == "set_default_search") { 1796#ifdef GECODE_HAS_SET_VARS 1797 Call* call = i->dynamicCast<Call>(); 1798 def_set_varsel = ann2svarsel(call->arg(0)->cast<Id>()->str(), rnd, decay); 1799 std::string r0; 1800 def_set_valsel = ann2svalsel(call->arg(1)->cast<Id>()->str(), r0, r0, rnd); 1801#else 1802 if (!ignoreUnknown) { 1803 err << "Warning, ignored search annotation: "; 1804 flatAnn[i]->print(err); 1805 err << std::endl; 1806 } 1807#endif 1808 } else if (i->isa<Call>() && i->cast<Call>()->id() == "float_default_search") { 1809#ifdef GECODE_HAS_FLOAT_VARS 1810 Call* call = i->dynamicCast<Call>(); 1811 def_float_varsel = ann2fvarsel(call->arg(0)->cast<Id>()->str(), rnd, decay); 1812 std::string r0; 1813 def_float_valsel = ann2fvalsel(call->arg(1)->cast<Id>()->str(), r0, r0); 1814#else 1815 if (!ignoreUnknown) { 1816 err << "Warning, ignored search annotation: float_default_search" << std::endl; 1817 } 1818#endif 1819 } else if (i->isa<Call>() && i->cast<Call>()->id() == "float_search") { 1820#ifdef GECODE_HAS_FLOAT_VARS 1821 Call* call = i->dynamicCast<Call>(); 1822 auto* vars = call->arg(0)->cast<ArrayLit>(); 1823 int k = static_cast<int>(vars->size()); 1824 for (int i = static_cast<int>(vars->size()); (i--) != 0;) { 1825 if (!((*vars)[i])->type().isvarfloat()) { 1826 k--; 1827 } 1828 } 1829 FloatVarArgs va(k); 1830 k = 0; 1831 std::vector<ASTString> names; 1832 for (unsigned int i = 0; i < vars->size(); i++) { 1833 if (!((*vars)[i])->type().isvarfloat()) { 1834 continue; 1835 } 1836 unsigned int idx = resolveVar(getVarDecl((*vars)[i])).index(); 1837 va[k++] = currentSpace->fv[idx]; 1838 fv_searched[idx] = true; 1839 names.push_back(getVarDecl((*vars)[i])->id()->str()); 1840 } 1841 std::string r0; 1842 std::string r1; 1843 // BrancherHandle bh = 1844 branch(*currentSpace, va, ann2fvarsel(call->arg(2)->cast<Id>()->str(), rnd, decay), 1845 ann2fvalsel(call->arg(3)->cast<Id>()->str(), r0, r1), 1846 nullptr //, 1847 //&varValPrintF 1848 ); 1849 // branchInfo.add(bh,r0,r1,names); 1850#else 1851 if (!ignoreUnknown) { 1852 err << "Warning, ignored search annotation: float_search" << std::endl; 1853 } 1854#endif 1855 } else { 1856 if (!ignoreUnknown) { 1857 err << "Warning, ignored search annotation: " << *i << std::endl; 1858 } 1859 } 1860 } // end for all annotations 1861} 1862 1863void GecodeSolverInstance::createBranchers(Annotation& ann, Expression* additionalAnn, int seed, 1864 double decay, bool ignoreUnknown, std::ostream& err) { 1865 // default search heuristics 1866 Rnd rnd(static_cast<unsigned int>(seed)); 1867 TieBreak<IntVarBranch> def_int_varsel = INT_VAR_AFC_SIZE_MAX(0.99); 1868 IntValBranch def_int_valsel = INT_VAL_MIN(); 1869 TieBreak<BoolVarBranch> def_bool_varsel = BOOL_VAR_AFC_MAX(0.99); 1870 BoolValBranch def_bool_valsel = BOOL_VAL_MIN(); 1871#ifdef GECODE_HAS_SET_VARS 1872 SetVarBranch def_set_varsel = SET_VAR_AFC_SIZE_MAX(0.99); 1873 SetValBranch def_set_valsel = SET_VAL_MIN_INC(); 1874#endif 1875#ifdef GECODE_HAS_FLOAT_VARS 1876 TieBreak<FloatVarBranch> def_float_varsel = FLOAT_VAR_SIZE_MIN(); 1877 FloatValBranch def_float_valsel = FLOAT_VAL_SPLIT_MIN(); 1878#endif 1879 1880 std::vector<bool> iv_searched(currentSpace->iv.size()); 1881 for (unsigned int i = currentSpace->iv.size(); (i--) != 0U;) { 1882 iv_searched[i] = false; 1883 } 1884 std::vector<bool> bv_searched(currentSpace->bv.size()); 1885 for (unsigned int i = currentSpace->bv.size(); (i--) != 0U;) { 1886 bv_searched[i] = false; 1887 } 1888#ifdef GECODE_HAS_SET_VARS 1889 std::vector<bool> sv_searched(currentSpace->sv.size()); 1890 for (unsigned int i = currentSpace->sv.size(); (i--) != 0U;) { 1891 sv_searched[i] = false; 1892 } 1893#endif 1894#ifdef GECODE_HAS_FLOAT_VARS 1895 std::vector<bool> fv_searched(currentSpace->fv.size()); 1896 for (unsigned int i = currentSpace->fv.size(); (i--) != 0U;) { 1897 fv_searched[i] = false; 1898 } 1899#endif 1900 1901 // solving annotations 1902 std::vector<Expression*> flatAnn; 1903 if (!ann.isEmpty()) { 1904 flattenSearchAnnotations(ann, flatAnn); 1905 } 1906 if (additionalAnn != nullptr) { 1907 flatAnn.push_back(additionalAnn); 1908 } 1909 if (!flatAnn.empty()) { 1910 setSearchStrategyFromAnnotation(flatAnn, iv_searched, bv_searched, 1911#ifdef GECODE_HAS_SET_VARS 1912 sv_searched, 1913#endif 1914#ifdef GECODE_HAS_FLOAT_VARS 1915 fv_searched, 1916#endif 1917 def_int_varsel, def_int_valsel, def_bool_varsel, 1918 def_bool_valsel, 1919#ifdef GECODE_HAS_SET_VARS 1920 def_set_varsel, def_set_valsel, 1921#endif 1922#ifdef GECODE_HAS_FLOAT_VARS 1923 def_float_varsel, def_float_valsel, 1924#endif 1925 rnd, decay, ignoreUnknown, err); 1926 } 1927 1928 int introduced = 0; 1929 int funcdep = 0; 1930 int searched = 0; 1931 for (int i = currentSpace->iv.size(); (i--) != 0;) { 1932 if (iv_searched[i]) { 1933 searched++; 1934 } else if (currentSpace->ivIntroduced[i]) { 1935 if (currentSpace->ivDefined[i]) { 1936 funcdep++; 1937 } else { 1938 introduced++; 1939 } 1940 } 1941 } 1942 IntVarArgs iv_sol(static_cast<int>(currentSpace->iv.size()) - (introduced + funcdep + searched)); 1943 IntVarArgs iv_tmp(introduced); 1944 for (int i = currentSpace->iv.size(), j = 0, k = 0; (i--) != 0U;) { 1945 if (iv_searched[i]) { 1946 continue; 1947 } 1948 if (currentSpace->ivIntroduced[i]) { 1949 if (currentSpace->ivIntroduced.size() >= i) { 1950 if (!currentSpace->ivDefined[i]) { 1951 iv_tmp[j++] = currentSpace->iv[i]; 1952 } 1953 } 1954 } else { 1955 iv_sol[k++] = currentSpace->iv[i]; 1956 } 1957 } 1958 // Collecting Boolean variables 1959 introduced = 0; 1960 funcdep = 0; 1961 searched = 0; 1962 for (int i = currentSpace->bv.size(); (i--) != 0;) { 1963 if (bv_searched[i]) { 1964 searched++; 1965 } else if (currentSpace->bvIntroduced[i]) { 1966 if (currentSpace->bvDefined[i]) { 1967 funcdep++; 1968 } else { 1969 introduced++; 1970 } 1971 } 1972 } 1973 BoolVarArgs bv_sol(static_cast<int>(currentSpace->bv.size()) - (introduced + funcdep + searched)); 1974 BoolVarArgs bv_tmp(introduced); 1975 for (int i = currentSpace->bv.size(), j = 0, k = 0; (i--) != 0;) { 1976 if (bv_searched[i]) { 1977 continue; 1978 } 1979 if (currentSpace->bvIntroduced[i]) { 1980 if (!currentSpace->bvDefined[i]) { 1981 bv_tmp[j++] = currentSpace->bv[i]; 1982 } 1983 } else { 1984 bv_sol[k++] = currentSpace->bv[i]; 1985 } 1986 } 1987 1988 if (iv_sol.size() > 0) { 1989 branch(*this->currentSpace, iv_sol, def_int_varsel, def_int_valsel); 1990 } 1991 if (bv_sol.size() > 0) { 1992 branch(*this->currentSpace, bv_sol, def_bool_varsel, def_bool_valsel); 1993 } 1994 1995 // std::cout << "DEBUG: branched over " << iv_sol.size() << " integer variables."<< std::endl; 1996 // std::cout << "DEBUG: branched over " << bv_sol.size() << " Boolean variables."<< std::endl; 1997#ifdef GECODE_HAS_FLOAT_VARS 1998 introduced = 0; 1999 funcdep = 0; 2000 searched = 0; 2001 for (int i = currentSpace->fv.size(); (i--) != 0;) { 2002 if (fv_searched[i]) { 2003 searched++; 2004 } else if (currentSpace->fvIntroduced[i]) { 2005 if (currentSpace->fvDefined[i]) { 2006 funcdep++; 2007 } else { 2008 introduced++; 2009 } 2010 } 2011 } 2012 FloatVarArgs fv_sol(static_cast<int>(currentSpace->fv.size()) - 2013 (introduced + funcdep + searched)); 2014 FloatVarArgs fv_tmp(introduced); 2015 for (int i = currentSpace->fv.size(), j = 0, k = 0; (i--) != 0;) { 2016 if (fv_searched[i]) { 2017 continue; 2018 } 2019 if (currentSpace->fvIntroduced[i]) { 2020 if (!currentSpace->fvDefined[i]) { 2021 fv_tmp[j++] = currentSpace->fv[i]; 2022 } 2023 } else { 2024 fv_sol[k++] = currentSpace->fv[i]; 2025 } 2026 } 2027 2028 if (fv_sol.size() > 0) { 2029 branch(*this->currentSpace, fv_sol, def_float_varsel, def_float_valsel); 2030 } 2031#endif 2032#ifdef GECODE_HAS_SET_VARS 2033 introduced = 0; 2034 funcdep = 0; 2035 searched = 0; 2036 for (int i = currentSpace->sv.size(); (i--) != 0;) { 2037 if (sv_searched[i]) { 2038 searched++; 2039 } else if (currentSpace->svIntroduced[i]) { 2040 if (currentSpace->svDefined[i]) { 2041 funcdep++; 2042 } else { 2043 introduced++; 2044 } 2045 } 2046 } 2047 SetVarArgs sv_sol(static_cast<int>(currentSpace->sv.size()) - (introduced + funcdep + searched)); 2048 SetVarArgs sv_tmp(introduced); 2049 for (int i = currentSpace->sv.size(), j = 0, k = 0; (i--) != 0;) { 2050 if (sv_searched[i]) { 2051 continue; 2052 } 2053 if (currentSpace->svIntroduced[i]) { 2054 if (!currentSpace->svDefined[i]) { 2055 sv_tmp[j++] = currentSpace->sv[i]; 2056 } 2057 } else { 2058 sv_sol[k++] = currentSpace->sv[i]; 2059 } 2060 } 2061 2062 if (sv_sol.size() > 0) { 2063 branch(*this->currentSpace, sv_sol, def_set_varsel, def_set_valsel); 2064 } 2065#endif 2066 2067 // branching on auxiliary variables 2068 currentSpace->ivAux = IntVarArray(*this->currentSpace, iv_tmp); 2069 currentSpace->bvAux = BoolVarArray(*this->currentSpace, bv_tmp); 2070 int n_aux = currentSpace->ivAux.size() + currentSpace->bvAux.size(); 2071#ifdef GECODE_HAS_SET_VARS 2072 currentSpace->svAux = SetVarArray(*this->currentSpace, sv_tmp); 2073 n_aux += currentSpace->svAux.size(); 2074#endif 2075#ifdef GECODE_HAS_FLOAT_VARS 2076 currentSpace->fvAux = FloatVarArray(*this->currentSpace, fv_tmp); 2077 n_aux += currentSpace->fvAux.size(); 2078#endif 2079 if (n_aux > 0) { 2080 AuxVarBrancher::post(*this->currentSpace, def_int_varsel, def_int_valsel, def_bool_varsel, 2081 def_bool_valsel 2082#ifdef GECODE_HAS_SET_VARS 2083 , 2084 def_set_varsel, def_set_valsel 2085#endif 2086#ifdef GECODE_HAS_FLOAT_VARS 2087 , 2088 def_float_varsel, def_float_valsel 2089#endif 2090 ); // end post 2091 // std::cout << "DEBUG: Posted aux-var-brancher for " << n_aux << " aux-variables" << std::endl; 2092 } // end if n_aux > 0 2093 // else 2094 // std::cout << "DEBUG: No aux vars to branch on." << std::endl; 2095} 2096 2097TieBreak<IntVarBranch> GecodeSolverInstance::ann2ivarsel(const ASTString s, Rnd& rnd, 2098 double decay) { 2099 if (s == "input_order") { 2100 return TieBreak<IntVarBranch>(INT_VAR_NONE()); 2101 } 2102 if (s == "first_fail") { 2103 return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN()); 2104 } 2105 if (s == "anti_first_fail") { 2106 return TieBreak<IntVarBranch>(INT_VAR_SIZE_MAX()); 2107 } 2108 if (s == "smallest") { 2109 return TieBreak<IntVarBranch>(INT_VAR_MIN_MIN()); 2110 } 2111 if (s == "largest") { 2112 return TieBreak<IntVarBranch>(INT_VAR_MAX_MAX()); 2113 } 2114 if (s == "occurrence") { 2115 return TieBreak<IntVarBranch>(INT_VAR_DEGREE_MAX()); 2116 } 2117 if (s == "max_regret") { 2118 return TieBreak<IntVarBranch>(INT_VAR_REGRET_MIN_MAX()); 2119 } 2120 if (s == "most_constrained") { 2121 return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN(), INT_VAR_DEGREE_MAX()); 2122 } 2123 if (s == "random") { 2124 return TieBreak<IntVarBranch>(INT_VAR_RND(rnd)); 2125 } 2126 if (s == "afc_min") { 2127 return TieBreak<IntVarBranch>(INT_VAR_AFC_MIN(decay)); 2128 } 2129 if (s == "afc_max") { 2130 return TieBreak<IntVarBranch>(INT_VAR_AFC_MAX(decay)); 2131 } 2132 if (s == "afc_size_min") { 2133 return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MIN(decay)); 2134 } 2135 if (s == "afc_size_max" || s == "dom_w_deg") { 2136 return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MAX(decay)); 2137 } 2138 if (s == "action_min") { 2139 return TieBreak<IntVarBranch>(INT_VAR_ACTION_MIN(decay)); 2140 } 2141 if (s == "action_max") { 2142 return TieBreak<IntVarBranch>(INT_VAR_ACTION_MAX(decay)); 2143 } 2144 if (s == "action_size_min") { 2145 return TieBreak<IntVarBranch>(INT_VAR_ACTION_SIZE_MIN(decay)); 2146 } 2147 if (s == "action_size_max") { 2148 return TieBreak<IntVarBranch>(INT_VAR_ACTION_SIZE_MAX(decay)); 2149 } 2150 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2151 return TieBreak<IntVarBranch>(INT_VAR_NONE()); 2152} 2153 2154Gecode::IntValBranch GecodeSolverInstance::ann2ivalsel(const ASTString s, std::string& r0, 2155 std::string& r1, Rnd& rnd) { 2156 if (s == "indomain_min") { 2157 r0 = "="; 2158 r1 = "!="; 2159 return INT_VAL_MIN(); 2160 } 2161 if (s == "indomain_max") { 2162 r0 = "="; 2163 r1 = "!="; 2164 return INT_VAL_MAX(); 2165 } 2166 if (s == "indomain_median") { 2167 r0 = "="; 2168 r1 = "!="; 2169 return INT_VAL_MED(); 2170 } 2171 if (s == "indomain_split") { 2172 r0 = "<="; 2173 r1 = ">"; 2174 return INT_VAL_SPLIT_MIN(); 2175 } 2176 if (s == "indomain_reverse_split") { 2177 r0 = ">"; 2178 r1 = "<="; 2179 return INT_VAL_SPLIT_MAX(); 2180 } 2181 if (s == "indomain_random") { 2182 r0 = "="; 2183 r1 = "!="; 2184 return INT_VAL_RND(rnd); 2185 } 2186 if (s == "indomain") { 2187 r0 = "="; 2188 r1 = "="; 2189 return INT_VALUES_MIN(); 2190 } 2191 if (s == "indomain_middle") { 2192 std::cerr << "Warning, replacing unsupported annotation " 2193 << "indomain_middle with indomain_median" << std::endl; 2194 r0 = "="; 2195 r1 = "!="; 2196 return INT_VAL_MED(); 2197 } 2198 if (s == "indomain_interval") { 2199 std::cerr << "Warning, replacing unsupported annotation " 2200 << "indomain_interval with indomain_split" << std::endl; 2201 r0 = "<="; 2202 r1 = ">"; 2203 return INT_VAL_SPLIT_MIN(); 2204 } 2205 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2206 r0 = "="; 2207 r1 = "!="; 2208 return INT_VAL_MIN(); 2209} 2210 2211TieBreak<BoolVarBranch> GecodeSolverInstance::ann2bvarsel(const ASTString s, Rnd& rnd, 2212 double decay) { 2213 if ((s == "input_order") || (s == "first_fail") || (s == "anti_first_fail") || 2214 (s == "smallest") || (s == "largest") || (s == "max_regret")) { 2215 return TieBreak<BoolVarBranch>(BOOL_VAR_NONE()); 2216 } 2217 if ((s == "occurrence") || (s == "most_constrained")) { 2218 return TieBreak<BoolVarBranch>(BOOL_VAR_DEGREE_MAX()); 2219 } 2220 if (s == "random") { 2221 return TieBreak<BoolVarBranch>(BOOL_VAR_RND(rnd)); 2222 } 2223 if ((s == "afc_min") || (s == "afc_size_min")) { 2224 return TieBreak<BoolVarBranch>(BOOL_VAR_AFC_MIN(decay)); 2225 } 2226 if ((s == "afc_max") || (s == "afc_size_max") || (s == "dom_w_deg")) { 2227 return TieBreak<BoolVarBranch>(BOOL_VAR_AFC_MAX(decay)); 2228 } 2229 if ((s == "action_min") && (s == "action_size_min")) { 2230 return TieBreak<BoolVarBranch>(BOOL_VAR_ACTION_MIN(decay)); 2231 } 2232 if ((s == "action_max") || (s == "action_size_max")) { 2233 return TieBreak<BoolVarBranch>(BOOL_VAR_ACTION_MAX(decay)); 2234 } 2235 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2236 return TieBreak<BoolVarBranch>(BOOL_VAR_NONE()); 2237} 2238 2239BoolValBranch GecodeSolverInstance::ann2bvalsel(const ASTString s, std::string& r0, std::string& r1, 2240 Rnd& rnd) { 2241 if (s == "indomain_min") { 2242 r0 = "="; 2243 r1 = "!="; 2244 return BOOL_VAL_MIN(); 2245 } 2246 if (s == "indomain_max") { 2247 r0 = "="; 2248 r1 = "!="; 2249 return BOOL_VAL_MAX(); 2250 } 2251 if (s == "indomain_median") { 2252 r0 = "="; 2253 r1 = "!="; 2254 return BOOL_VAL_MIN(); 2255 } 2256 if (s == "indomain_split") { 2257 r0 = "<="; 2258 r1 = ">"; 2259 return BOOL_VAL_MIN(); 2260 } 2261 if (s == "indomain_reverse_split") { 2262 r0 = ">"; 2263 r1 = "<="; 2264 return BOOL_VAL_MAX(); 2265 } 2266 if (s == "indomain_random") { 2267 r0 = "="; 2268 r1 = "!="; 2269 return BOOL_VAL_RND(rnd); 2270 } 2271 if (s == "indomain") { 2272 r0 = "="; 2273 r1 = "="; 2274 return BOOL_VAL_MIN(); 2275 } 2276 if (s == "indomain_middle") { 2277 std::cerr << "Warning, replacing unsupported annotation " 2278 << "indomain_middle with indomain_median" << std::endl; 2279 r0 = "="; 2280 r1 = "!="; 2281 return BOOL_VAL_MIN(); 2282 } 2283 if (s == "indomain_interval") { 2284 std::cerr << "Warning, replacing unsupported annotation " 2285 << "indomain_interval with indomain_split" << std::endl; 2286 r0 = "<="; 2287 r1 = ">"; 2288 return BOOL_VAL_MIN(); 2289 } 2290 std::cerr << "Warning, ignored search annotation: " << s << "\n"; 2291 r0 = "="; 2292 r1 = "!="; 2293 return BOOL_VAL_MIN(); 2294} 2295 2296BoolAssign GecodeSolverInstance::ann2asnbvalsel(const ASTString s, Rnd& rnd) { 2297 if ((s == "indomain_min") || (s == "indomain_median")) { 2298 return BOOL_ASSIGN_MIN(); 2299 } 2300 if (s == "indomain_max") { 2301 return BOOL_ASSIGN_MAX(); 2302 } 2303 if (s == "indomain_random") { 2304 return BOOL_ASSIGN_RND(rnd); 2305 } 2306 std::cerr << "Warning, ignored search annotation: " << s << "\n"; 2307 return BOOL_ASSIGN_MIN(); 2308} 2309 2310IntAssign GecodeSolverInstance::ann2asnivalsel(const ASTString s, Rnd& rnd) { 2311 if (s == "indomain_min") { 2312 return INT_ASSIGN_MIN(); 2313 } 2314 if (s == "indomain_max") { 2315 return INT_ASSIGN_MAX(); 2316 } 2317 if (s == "indomain_median") { 2318 return INT_ASSIGN_MED(); 2319 } 2320 if (s == "indomain_random") { 2321 return INT_ASSIGN_RND(rnd); 2322 } 2323 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2324 return INT_ASSIGN_MIN(); 2325} 2326 2327#ifdef GECODE_HAS_SET_VARS 2328SetVarBranch GecodeSolverInstance::ann2svarsel(const ASTString s, Rnd& rnd, double decay) { 2329 if (s == "input_order") { 2330 return SET_VAR_NONE(); 2331 } 2332 if (s == "first_fail") { 2333 return SET_VAR_SIZE_MIN(); 2334 } 2335 if (s == "anti_first_fail") { 2336 return SET_VAR_SIZE_MAX(); 2337 } 2338 if (s == "smallest") { 2339 return SET_VAR_MIN_MIN(); 2340 } 2341 if (s == "largest") { 2342 return SET_VAR_MAX_MAX(); 2343 } 2344 if (s == "afc_min") { 2345 return SET_VAR_AFC_MIN(decay); 2346 } 2347 if (s == "afc_max") { 2348 return SET_VAR_AFC_MAX(decay); 2349 } 2350 if (s == "afc_size_min") { 2351 return SET_VAR_AFC_SIZE_MIN(decay); 2352 } 2353 if (s == "afc_size_max") { 2354 return SET_VAR_AFC_SIZE_MAX(decay); 2355 } 2356 if (s == "action_min") { 2357 return SET_VAR_ACTION_MIN(decay); 2358 } 2359 if (s == "action_max") { 2360 return SET_VAR_ACTION_MAX(decay); 2361 } 2362 if (s == "action_size_min") { 2363 return SET_VAR_ACTION_SIZE_MIN(decay); 2364 } 2365 if (s == "action_size_max") { 2366 return SET_VAR_ACTION_SIZE_MAX(decay); 2367 } 2368 if (s == "random") { 2369 return SET_VAR_RND(rnd); 2370 } 2371 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2372 return SET_VAR_NONE(); 2373} 2374 2375SetValBranch GecodeSolverInstance::ann2svalsel(const ASTString s, std::string& r0, std::string& r1, 2376 Rnd& rnd) { 2377 (void)rnd; 2378 if (s == "indomain_min") { 2379 r0 = "in"; 2380 r1 = "not in"; 2381 return SET_VAL_MIN_INC(); 2382 } 2383 if (s == "indomain_max") { 2384 r0 = "in"; 2385 r1 = "not in"; 2386 return SET_VAL_MAX_INC(); 2387 } 2388 if (s == "outdomain_min") { 2389 r1 = "in"; 2390 r0 = "not in"; 2391 return SET_VAL_MIN_EXC(); 2392 } 2393 if (s == "outdomain_max") { 2394 r1 = "in"; 2395 r0 = "not in"; 2396 return SET_VAL_MAX_EXC(); 2397 } 2398 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2399 r0 = "in"; 2400 r1 = "not in"; 2401 return SET_VAL_MIN_INC(); 2402} 2403#endif 2404 2405#ifdef GECODE_HAS_FLOAT_VARS 2406TieBreak<FloatVarBranch> GecodeSolverInstance::ann2fvarsel(const ASTString s, Rnd& rnd, 2407 double decay) { 2408 if (s == "input_order") { 2409 return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE()); 2410 } 2411 if (s == "first_fail") { 2412 return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN()); 2413 } 2414 if (s == "anti_first_fail") { 2415 return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MAX()); 2416 } 2417 if (s == "smallest") { 2418 return TieBreak<FloatVarBranch>(FLOAT_VAR_MIN_MIN()); 2419 } 2420 if (s == "largest") { 2421 return TieBreak<FloatVarBranch>(FLOAT_VAR_MAX_MAX()); 2422 } 2423 if (s == "occurrence") { 2424 return TieBreak<FloatVarBranch>(FLOAT_VAR_DEGREE_MAX()); 2425 } 2426 if (s == "most_constrained") { 2427 return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN(), FLOAT_VAR_DEGREE_MAX()); 2428 } 2429 if (s == "random") { 2430 return TieBreak<FloatVarBranch>(FLOAT_VAR_RND(rnd)); 2431 } 2432 if (s == "afc_min") { 2433 return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MIN(decay)); 2434 } 2435 if (s == "afc_max") { 2436 return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MAX(decay)); 2437 } 2438 if (s == "afc_size_min") { 2439 return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MIN(decay)); 2440 } 2441 if (s == "afc_size_max") { 2442 return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MAX(decay)); 2443 } 2444 if (s == "action_min") { 2445 return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_MIN(decay)); 2446 } 2447 if (s == "action_max") { 2448 return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_MAX(decay)); 2449 } 2450 if (s == "action_size_min") { 2451 return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_SIZE_MIN(decay)); 2452 } 2453 if (s == "action_size_max") { 2454 return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_SIZE_MAX(decay)); 2455 } 2456 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2457 return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE()); 2458} 2459 2460FloatValBranch GecodeSolverInstance::ann2fvalsel(const ASTString s, std::string& r0, 2461 std::string& r1) { 2462 if (s == "indomain_split") { 2463 r0 = "<="; 2464 r1 = ">"; 2465 return FLOAT_VAL_SPLIT_MIN(); 2466 } 2467 if (s == "indomain_reverse_split") { 2468 r1 = "<="; 2469 r0 = ">"; 2470 return FLOAT_VAL_SPLIT_MAX(); 2471 } 2472 std::cerr << "Warning, ignored search annotation: " << s << std::endl; 2473 r0 = "<="; 2474 r1 = ">"; 2475 return FLOAT_VAL_SPLIT_MIN(); 2476} 2477#endif 2478} // namespace MiniZinc