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